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
data/README.md CHANGED
@@ -40,6 +40,9 @@ Finding a single issue:
40
40
 
41
41
  Default auth type is now Basic auth. Cookie auth will be deprecated in the next version.
42
42
 
43
+ ## Changes from 0.3.0
44
+
45
+ * User and Avatars are now supported.
43
46
 
44
47
  ## Changes from 0.2.2
45
48
 
@@ -17,8 +17,6 @@ Gem::Specification.new do |s|
17
17
  s.add_runtime_dependency 'hashie', '>= 1.1'
18
18
  s.add_runtime_dependency 'json', '>= 1.6', '< 1.9.0'
19
19
  s.add_development_dependency 'rspec', '~> 2.6'
20
- s.add_development_dependency 'gemcutter'
21
-
22
20
  s.add_development_dependency 'rake'
23
21
  s.add_development_dependency 'fakeweb', '~> 1.3.0'
24
22
 
@@ -15,12 +15,16 @@ require 'jiralicious/issue/comment'
15
15
  require 'jiralicious/issue/watchers'
16
16
  require 'jiralicious/issue/transitions'
17
17
  require 'jiralicious/project'
18
+ require 'jiralicious/project/avatar'
18
19
  require 'jiralicious/search'
19
20
  require 'jiralicious/search_result'
20
21
  require 'jiralicious/session'
22
+ require 'jiralicious/user'
23
+ require 'jiralicious/user/avatar'
21
24
  require 'jiralicious/basic_session'
22
25
  require 'jiralicious/cookie_session'
23
26
  require 'jiralicious/configuration'
27
+ require 'jiralicious/avatar'
24
28
 
25
29
  ##
26
30
  # The Jiralicious module standard options and methods
@@ -0,0 +1,101 @@
1
+ # encoding: utf-8
2
+ module Jiralicious
3
+ ##
4
+ # Avatars in the Project class.
5
+ #
6
+ class Avatar < Jiralicious::Base
7
+
8
+ ##
9
+ # Initialization Method
10
+ #
11
+ # [Arguments]
12
+ # :decoded_json (optional) decoded json object
13
+ #
14
+ def initialize(decoded_json = nil)
15
+ @loaded = false
16
+ if !decoded_json.nil?
17
+ if decoded_json.is_a? Hash
18
+ decoded_json = properties_from_hash(decoded_json)
19
+ super(decoded_json)
20
+ parse!(decoded_json)
21
+ self.each do |k, v|
22
+ if v.is_a? Hash
23
+ self[k] = self.class.new(v)
24
+ elsif v.is_a? Array
25
+ v.each_index do |i|
26
+ if v[i].is_a? Hash
27
+ v[i] = self.class.new(v[i])
28
+ end
29
+ end
30
+ self[k] = v
31
+ end
32
+ end
33
+ @loaded = true
34
+ else
35
+ i = 0;
36
+ decoded_json.each do |list|
37
+ if !list['id'].nil?
38
+ if numeric? list['id']
39
+ id = :"id_#{list['id']}"
40
+ else
41
+ id = :"#{list['id']}"
42
+ end
43
+ else
44
+ id = :"_#{i}"
45
+ i += 1
46
+ end
47
+ self.class.property id
48
+ self[id] = self.class.new(list)
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ class << self
55
+
56
+ ##
57
+ # Gets a list of available avatars
58
+ #
59
+ # [Arguments]
60
+ # :key (required) avatar type = Project or User
61
+ #
62
+ def system(key, options = {})
63
+ response = fetch({:method => :get, :key => "#{key}/system", :body => options})
64
+ return self.new(response.parsed_response)
65
+ end
66
+
67
+ ##
68
+ # Creates temporary avatar
69
+ #
70
+ # [Arguments]
71
+ # :key (required) avatar type = Project or User
72
+ #
73
+ # :filename (required) file to upload
74
+ #
75
+ # :size (required) size of the file
76
+ #
77
+ def temporary(key, options = {})
78
+ response = fetch({:method => :post, :key => "#{key}/temporary", :body => options})
79
+ return self.new(response.parsed_response)
80
+ end
81
+
82
+ ##
83
+ # Updates the cropping on a temporary avatar
84
+ #
85
+ # [Arguments]
86
+ # :key (required) avatar type = Project or User
87
+ #
88
+ # :cropperWidth (optional) width of the image
89
+ #
90
+ # :cropperOffsetX (optional) X Offset on image
91
+ #
92
+ # :cropperOffsety (optional) Y Offset on image
93
+ #
94
+ # :needsCropping (optional) Boolean if needs cropping
95
+ #
96
+ def temporary_crop(key, options = {})
97
+ response = fetch({:method => :post, :key => "#{key}/temporaryCrop", :body => options})
98
+ end
99
+ end
100
+ end
101
+ end
@@ -22,6 +22,9 @@ module Jiralicious
22
22
  # Adds an underscore (_) before a numeric field.
23
23
  # This ensures that numeric fields will be treated as strings.
24
24
  #
25
+ # [Arguments]
26
+ # :hash (required) hash to be added to properties
27
+ #
25
28
  def properties_from_hash(hash)
26
29
  hash.inject({}) do |newhash, (k, v)|
27
30
  k = k.gsub("-", "_")
@@ -34,8 +37,14 @@ module Jiralicious
34
37
 
35
38
  class << self
36
39
  ##
37
- # Finds the specified key in relation to the current class. This is based on the
38
- # inheritance and will create an error if called from the Base Class directly.
40
+ # Finds the specified key in relation to the current class.
41
+ # This is based on the inheritance and will create an error
42
+ # if called from the Base Class directly.
43
+ #
44
+ # [Arguments]
45
+ # :key (required) object key to find
46
+ #
47
+ # :reload (required) is object reloading forced
39
48
  #
40
49
  def find(key, options = {})
41
50
  response = fetch({:key => key})
@@ -47,9 +56,10 @@ module Jiralicious
47
56
  end
48
57
 
49
58
  ##
50
- # Searches for all objects of the inheritance class. This method can create very large
51
- # datasets and is not recommended for any request that could slow down either Jira or
52
- # the Ruby application.
59
+ # Searches for all objects of the inheritance class. This
60
+ # method can create very large datasets and is not recommended
61
+ # for any request that could slow down either Jira or the
62
+ # Ruby application.
53
63
  #
54
64
  def find_all
55
65
  response = fetch()
@@ -72,9 +82,27 @@ module Jiralicious
72
82
  end
73
83
 
74
84
  ##
75
- # uses the options to build the URI options necessary to handle the request.
76
- # Some options are defaulted if not explicit while others are only necessary
77
- # under specific conditions.
85
+ # uses the options to build the URI options necessary to handle the
86
+ # request. Some options are defaulted if not explicit while others
87
+ # are only necessary under specific conditions.
88
+ #
89
+ #
90
+ # [Arguments]
91
+ # :key (optional) key of object to fetch
92
+ #
93
+ # :method (optional) limited to the standard request types default of :get
94
+ #
95
+ # :parent (optional) boolean will the parent object be used
96
+ #
97
+ # :parent_key (optional) parent's key (must set :parent to use)
98
+ #
99
+ # :body (optional) fields to be sent with the fetch
100
+ #
101
+ # :body_override (optional) corrects issues in :body if set
102
+ #
103
+ # :body_to_params (optional) forces body to be appended to URI
104
+ #
105
+ # :url (optional) overrides auto generated URI with custom URI
78
106
  #
79
107
  def fetch(options = {})
80
108
  options[:method] = :get unless [:get, :post, :put, :delete].include?(options[:method])
@@ -88,7 +116,7 @@ module Jiralicious
88
116
  options[:params_uri] = "?#{options[:body].to_params}" unless options[:body].nil? || options[:body].empty?
89
117
  options[:body_uri] = nil
90
118
  end
91
- options[:url_uri] = options[:url].nil? ? "#{Jiralicious.rest_path}/#{options[:parent_uri]}#{endpoint_name}/#{options[:key]}#{options[:params_uri]}" : options[:url]
119
+ options[:url_uri] = options[:url].nil? ? "#{Jiralicious.rest_path}/#{options[:parent_uri]}#{endpoint_name}/#{options[:key]}#{options[:params_uri]}" : "#{options[:url]}#{options[:params_uri]}"
92
120
  Jiralicious.session.request(options[:method], options[:url_uri], :handler => handler, :body => options[:body_uri].to_json)
93
121
  end
94
122
 
@@ -102,11 +130,11 @@ module Jiralicious
102
130
  when 200..204
103
131
  response
104
132
  when 400
105
- raise Jiralicious::TransitionError.new(response)
133
+ raise Jiralicious::TransitionError.new(response.inspect)
106
134
  when 404
107
- raise Jiralicious::IssueNotFound.new(response)
135
+ raise Jiralicious::IssueNotFound.new(response.inspect)
108
136
  else
109
- raise Jiralicious::JiraError.new(response)
137
+ raise Jiralicious::JiraError.new(response.inspect)
110
138
  end
111
139
  end
112
140
  end
@@ -129,9 +157,9 @@ module Jiralicious
129
157
  end
130
158
 
131
159
  ##
132
- # Searches for all objects of the inheritance class. This method can create very large
133
- # datasets and is not recommended for any request that could slow down either Jira or
134
- # the Ruby application.
160
+ # Searches for all objects of the inheritance class. This method can
161
+ # create very large datasets and is not recommended for any request
162
+ # that could slow down either Jira or the Ruby application.
135
163
  #
136
164
  def all
137
165
  self.class.all
@@ -156,6 +184,13 @@ module Jiralicious
156
184
  # Overrides the default method_missing check. This override is used in lazy
157
185
  # loading to ensure that the requested field or method is truly unavailable.
158
186
  #
187
+ # [Arguments]
188
+ # :meth (system)
189
+ #
190
+ # :args (system)
191
+ #
192
+ # :block (system)
193
+ #
159
194
  def method_missing(meth, *args, &block)
160
195
  if !loaded?
161
196
  self.loaded = true
@@ -169,6 +204,9 @@ module Jiralicious
169
204
  ##
170
205
  # Validates if the provided object is a numeric value
171
206
  #
207
+ # [Arguments]
208
+ # :object (required) object to be tested
209
+ #
172
210
  def numeric?(object)
173
211
  true if Float(object) rescue false
174
212
  end
@@ -1,9 +1,12 @@
1
1
  # encoding: utf-8
2
2
  require 'ostruct'
3
3
  module Jiralicious
4
+ ##
5
+ # Base configuration module for Jiralicious
6
+ #
4
7
  module Configuration
5
8
  # Array of available attributes
6
- VALID_OPTIONS = [:username, :password, :uri, :api_version, :auth_type]
9
+ VALID_OPTIONS = [:username, :password, :uri, :api_version, :auth_type, :project]
7
10
  # Default user name set prior to login attempt
8
11
  DEFAULT_USERNAME = nil
9
12
  # Default password set prior to login attempt
@@ -15,7 +18,9 @@ module Jiralicious
15
18
  # Default API Version can be set any valid version or "latest"
16
19
  DEFAULT_API_VERSION = "latest"
17
20
 
21
+ ##
18
22
  # Enables block configuration mode
23
+ #
19
24
  def configure
20
25
  yield self
21
26
  end
@@ -23,19 +28,28 @@ module Jiralicious
23
28
  # Provides access to the array of attributes
24
29
  attr_accessor *VALID_OPTIONS
25
30
 
31
+ ##
26
32
  # Reset when extended into class
33
+ #
34
+ # [Arguments]
35
+ # :base (required)
36
+ #
27
37
  def self.extended(base)
28
38
  base.reset
29
39
  end
30
40
 
41
+ ##
31
42
  # Pass options to set the values
43
+ #
32
44
  def options
33
45
  VALID_OPTIONS.inject({}) do |option, key|
34
46
  option.merge!(key => send(key))
35
47
  end
36
48
  end
37
49
 
50
+ ##
38
51
  # Resets all attributes to default values
52
+ #
39
53
  def reset
40
54
  self.username = DEFAULT_USERNAME
41
55
  self.password = DEFAULT_PASSWORD
@@ -47,8 +61,9 @@ module Jiralicious
47
61
  ##
48
62
  # Loads the provided YML file.
49
63
  #
50
- # Can provide either direct or relational path to the file. It is recommended to send a direct path
51
- # due to dynamic loading and/or different file locations due to different deployment methods.
64
+ # Can provide either direct or relational path to the file.
65
+ # It is recommended to send a direct path due to dynamic
66
+ # loading and/or different file locations due to different deployment methods.
52
67
  #
53
68
  # [Direct Path] /usr/project/somepath_to_file/jira.yml
54
69
  #
@@ -56,12 +71,23 @@ module Jiralicious
56
71
  #
57
72
  # "./config/jira.yml"
58
73
  #
59
- def load_yml(yml_file)
74
+ # [Arguments]
75
+ # :yml_file (required) path to file to load
76
+ #
77
+ # :mode (optional) used to define environment type
78
+ #
79
+ def load_yml(yml_file, mode=nil)
60
80
  if File.exist?(yml_file)
61
81
  yml_cfg = OpenStruct.new(YAML.load_file(yml_file))
82
+ if mode.nil? || mode =~ /production/i
62
83
  yml_cfg.jira.each do |k, v|
63
84
  instance_variable_set("@#{k}", v)
64
85
  end
86
+ else
87
+ yml_cfg.send(mode).each do |k,v|
88
+ instance_variable_set("@#{k}", v)
89
+ end
90
+ end
65
91
  else
66
92
  reset
67
93
  end
@@ -1,15 +1,19 @@
1
1
  # encoding: utf-8
2
2
  module Jiralicious
3
3
  ##
4
- # The CustomFieldOption provides a list of available custom field options. This method is
5
- # used in lazy loading and can be used to validate options prior to updating the issue.
4
+ # The CustomFieldOption provides a list of available custom
5
+ # field options. This method is used in lazy loading and can
6
+ # be used to validate options prior to updating the issue.
6
7
  #
7
8
  class CustomFieldOption < Jiralicious::Base
8
9
 
9
10
  ##
10
11
  # Initialization Method
11
12
  #
12
- def initialize(decoded_json, default = nil, &blk)
13
+ # [Arguments]
14
+ # :decoded_json (optional) rubyized json object
15
+ #
16
+ def initialize(decoded_json)
13
17
  @loaded = false
14
18
  if decoded_json.is_a? Hash
15
19
  properties_from_hash(decoded_json)
@@ -1,17 +1,27 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Jiralicious
4
+ # General Jira error
4
5
  class JiraError < StandardError; end
6
+ # AuthenticateError
5
7
  class AuthenticationError < StandardError; end
8
+ # NotLoggedIn error
6
9
  class NotLoggedIn < AuthenticationError; end
10
+ # InvalidLogin error
7
11
  class InvalidLogin < AuthenticationError; end
8
12
 
9
13
  # These are in the JIRA API docs. Not sure about specifics, as the docs don't
10
14
  # mention them. Added here for completeness and future implementation.
11
15
  # http://confluence.atlassian.com/display/JIRA/JIRA+REST+API+%28Alpha%29+Tutorial
16
+
17
+ # Cookie has Expired (depricated)
12
18
  class CookieExpired < AuthenticationError; end
19
+ # Captcha is Required (not used)
13
20
  class CaptchaRequired < AuthenticationError; end
21
+ # IssueNotFound error (any invalid object)
14
22
  class IssueNotFound < StandardError; end
23
+ # JQL Error (error in JQL search(
15
24
  class JqlError < StandardError; end
25
+ # Transition Error
16
26
  class TransitionError < StandardError; end
17
27
  end
@@ -1,17 +1,23 @@
1
1
  # encoding: utf-8
2
2
  module Jiralicious
3
3
  ##
4
- # The Field class is used in multiple classes as a support object. This class
5
- # is designed as a Object Oriented Method of viewing the Jira JSON/Hash.
4
+ # The Field class is used in multiple classes as a support
5
+ # object. This class is designed as a Object Oriented Method
6
+ # of viewing the Jira JSON/Hash.
6
7
  #
7
8
  class Field < Jiralicious::Base
8
9
  ##
9
10
  # Initialization Method
10
11
  #
11
- # Builds the dynamic Field object from either a Hash or Array. The decoded JSON object can be nested
12
- # as deep as necessary but it is recommended that JSON objects are no deeper then 5 levels maximum.
12
+ # Builds the dynamic Field object from either a Hash or Array.
13
+ # The decoded JSON object can be nested as deep as necessary
14
+ # but it is recommended that JSON objects are no deeper then
15
+ # 5 levels maximum.
13
16
  #
14
- def initialize(decoded_json, default = nil, &blk)
17
+ # [Arguments]
18
+ # :decoded_json (optional) rubyized json object
19
+ #
20
+ def initialize(decoded_json)
15
21
  @loaded = false
16
22
  if decoded_json.is_a? Hash
17
23
  decoded_json = properties_from_hash(decoded_json)
@@ -31,15 +37,20 @@ module Jiralicious
31
37
  end
32
38
  @loaded = true
33
39
  else
40
+ i = 0;
34
41
  decoded_json.each do |list|
35
- if numeric? list['id']
36
- id = :"id_#{list['id']}"
37
- else
38
- id = :"#{list['id']}"
39
- end
42
+ if !list['id'].nil?
43
+ if numeric? list['id']
44
+ id = :"id_#{list['id']}"
45
+ else
46
+ id = :"#{list['id']}"
47
+ end
48
+ else
49
+ id = :"_#{i}"
50
+ i += 1
51
+ end
40
52
  self.class.property id
41
- out self.class.new(list)
42
- self.merge!({id => out})
53
+ self[id] = self.class.new(list)
43
54
  end
44
55
  end
45
56
  end