jira-ruby-dmg 0.1.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.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.travis.yml +6 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +46 -0
- data/README.rdoc +309 -0
- data/Rakefile +28 -0
- data/example.rb +119 -0
- data/http-basic-example.rb +112 -0
- data/jira-ruby-dmg.gemspec +28 -0
- data/lib/jira/base.rb +497 -0
- data/lib/jira/base_factory.rb +49 -0
- data/lib/jira/client.rb +165 -0
- data/lib/jira/has_many_proxy.rb +43 -0
- data/lib/jira/http_client.rb +69 -0
- data/lib/jira/http_error.rb +16 -0
- data/lib/jira/oauth_client.rb +84 -0
- data/lib/jira/railtie.rb +10 -0
- data/lib/jira/request_client.rb +18 -0
- data/lib/jira/resource/attachment.rb +12 -0
- data/lib/jira/resource/comment.rb +14 -0
- data/lib/jira/resource/component.rb +10 -0
- data/lib/jira/resource/field.rb +10 -0
- data/lib/jira/resource/filter.rb +15 -0
- data/lib/jira/resource/issue.rb +76 -0
- data/lib/jira/resource/issuetype.rb +10 -0
- data/lib/jira/resource/priority.rb +10 -0
- data/lib/jira/resource/project.rb +31 -0
- data/lib/jira/resource/status.rb +10 -0
- data/lib/jira/resource/transition.rb +33 -0
- data/lib/jira/resource/user.rb +14 -0
- data/lib/jira/resource/version.rb +10 -0
- data/lib/jira/resource/worklog.rb +16 -0
- data/lib/jira/tasks.rb +0 -0
- data/lib/jira/version.rb +3 -0
- data/lib/jira.rb +33 -0
- data/lib/tasks/generate.rake +18 -0
- data/spec/integration/attachment_spec.rb +23 -0
- data/spec/integration/comment_spec.rb +55 -0
- data/spec/integration/component_spec.rb +42 -0
- data/spec/integration/field_spec.rb +35 -0
- data/spec/integration/issue_spec.rb +94 -0
- data/spec/integration/issuetype_spec.rb +26 -0
- data/spec/integration/priority_spec.rb +27 -0
- data/spec/integration/project_spec.rb +56 -0
- data/spec/integration/status_spec.rb +27 -0
- data/spec/integration/transition_spec.rb +52 -0
- data/spec/integration/user_spec.rb +25 -0
- data/spec/integration/version_spec.rb +43 -0
- data/spec/integration/worklog_spec.rb +55 -0
- data/spec/jira/base_factory_spec.rb +46 -0
- data/spec/jira/base_spec.rb +586 -0
- data/spec/jira/client_spec.rb +188 -0
- data/spec/jira/has_many_proxy_spec.rb +45 -0
- data/spec/jira/http_client_spec.rb +109 -0
- data/spec/jira/http_error_spec.rb +25 -0
- data/spec/jira/oauth_client_spec.rb +111 -0
- data/spec/jira/request_client_spec.rb +14 -0
- data/spec/jira/resource/attachment_spec.rb +20 -0
- data/spec/jira/resource/filter_spec.rb +97 -0
- data/spec/jira/resource/issue_spec.rb +107 -0
- data/spec/jira/resource/project_factory_spec.rb +13 -0
- data/spec/jira/resource/project_spec.rb +70 -0
- data/spec/jira/resource/worklog_spec.rb +24 -0
- data/spec/mock_responses/attachment/10000.json +20 -0
- data/spec/mock_responses/component/10000.invalid.put.json +5 -0
- data/spec/mock_responses/component/10000.json +39 -0
- data/spec/mock_responses/component/10000.put.json +39 -0
- data/spec/mock_responses/component.post.json +28 -0
- data/spec/mock_responses/field/1.json +15 -0
- data/spec/mock_responses/field.json +32 -0
- data/spec/mock_responses/issue/10002/comment/10000.json +29 -0
- data/spec/mock_responses/issue/10002/comment/10000.put.json +29 -0
- data/spec/mock_responses/issue/10002/comment.json +65 -0
- data/spec/mock_responses/issue/10002/comment.post.json +29 -0
- data/spec/mock_responses/issue/10002/transitions.json +49 -0
- data/spec/mock_responses/issue/10002/transitions.post.json +1 -0
- data/spec/mock_responses/issue/10002/worklog/10000.json +31 -0
- data/spec/mock_responses/issue/10002/worklog/10000.put.json +30 -0
- data/spec/mock_responses/issue/10002/worklog.json +98 -0
- data/spec/mock_responses/issue/10002/worklog.post.json +30 -0
- data/spec/mock_responses/issue/10002.invalid.put.json +6 -0
- data/spec/mock_responses/issue/10002.json +126 -0
- data/spec/mock_responses/issue/10002.put.missing_field_update.json +6 -0
- data/spec/mock_responses/issue.json +1108 -0
- data/spec/mock_responses/issue.post.json +5 -0
- data/spec/mock_responses/issuetype/5.json +8 -0
- data/spec/mock_responses/issuetype.json +42 -0
- data/spec/mock_responses/priority/1.json +8 -0
- data/spec/mock_responses/priority.json +42 -0
- data/spec/mock_responses/project/SAMPLEPROJECT.issues.json +1108 -0
- data/spec/mock_responses/project/SAMPLEPROJECT.json +84 -0
- data/spec/mock_responses/project.json +12 -0
- data/spec/mock_responses/status/1.json +7 -0
- data/spec/mock_responses/status.json +37 -0
- data/spec/mock_responses/user_username=admin.json +17 -0
- data/spec/mock_responses/version/10000.invalid.put.json +5 -0
- data/spec/mock_responses/version/10000.json +11 -0
- data/spec/mock_responses/version/10000.put.json +7 -0
- data/spec/mock_responses/version.post.json +7 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/support/clients_helper.rb +16 -0
- data/spec/support/matchers/have_attributes.rb +11 -0
- data/spec/support/matchers/have_many.rb +9 -0
- data/spec/support/matchers/have_one.rb +5 -0
- data/spec/support/shared_examples/integration.rb +190 -0
- metadata +301 -0
@@ -0,0 +1,43 @@
|
|
1
|
+
#
|
2
|
+
# Whenever a collection from a has_many relationship is accessed, an instance
|
3
|
+
# of this class is returned. This instance wraps the Array of instances in
|
4
|
+
# the collection with an extra build method, which allows new instances to be
|
5
|
+
# built on the collection with the correct properties.
|
6
|
+
#
|
7
|
+
# In practice, instances of this class behave exactly like an Array.
|
8
|
+
#
|
9
|
+
class JIRA::HasManyProxy
|
10
|
+
|
11
|
+
attr_reader :target_class, :parent
|
12
|
+
attr_accessor :collection
|
13
|
+
|
14
|
+
def initialize(parent, target_class, collection = [])
|
15
|
+
@parent = parent
|
16
|
+
@target_class = target_class
|
17
|
+
@collection = collection
|
18
|
+
end
|
19
|
+
|
20
|
+
# Builds an instance of this class with the correct parent.
|
21
|
+
# For example, issue.comments.build(attrs) will initialize a
|
22
|
+
# comment as follows:
|
23
|
+
#
|
24
|
+
# JIRA::Resource::Comment.new(issue.client,
|
25
|
+
# :attrs => attrs,
|
26
|
+
# :issue => issue)
|
27
|
+
def build(attrs = {})
|
28
|
+
resource = target_class.new(parent.client, :attrs => attrs, parent.to_sym => parent)
|
29
|
+
collection << resource
|
30
|
+
resource
|
31
|
+
end
|
32
|
+
|
33
|
+
# Forces an HTTP request to fetch all instances of the target class that
|
34
|
+
# are associated with the parent
|
35
|
+
def all
|
36
|
+
target_class.all(parent.client, parent.to_sym => parent)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Delegate any missing methods to the collection that this proxy wraps
|
40
|
+
def method_missing(method_name, *args, &block)
|
41
|
+
collection.send(method_name, *args, &block)
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'net/https'
|
3
|
+
require 'cgi/cookie'
|
4
|
+
|
5
|
+
module JIRA
|
6
|
+
class HttpClient < RequestClient
|
7
|
+
|
8
|
+
DEFAULT_OPTIONS = {
|
9
|
+
:username => '',
|
10
|
+
:password => ''
|
11
|
+
}
|
12
|
+
|
13
|
+
attr_reader :options
|
14
|
+
|
15
|
+
def initialize(options)
|
16
|
+
@options = DEFAULT_OPTIONS.merge(options)
|
17
|
+
@cookies = {}
|
18
|
+
end
|
19
|
+
|
20
|
+
def make_request(http_method, path, body='', headers={})
|
21
|
+
request = Net::HTTP.const_get(http_method.to_s.capitalize).new(path, headers)
|
22
|
+
request.body = body unless body.nil?
|
23
|
+
add_cookies(request) if options[:use_cookies]
|
24
|
+
request.basic_auth(@options[:username], @options[:password])
|
25
|
+
response = basic_auth_http_conn.request(request)
|
26
|
+
store_cookies(response) if options[:use_cookies]
|
27
|
+
response
|
28
|
+
end
|
29
|
+
|
30
|
+
def basic_auth_http_conn
|
31
|
+
http_conn(uri)
|
32
|
+
end
|
33
|
+
|
34
|
+
def http_conn(uri)
|
35
|
+
if @options[:proxy_address]
|
36
|
+
http_class = Net::HTTP::Proxy(@options[:proxy_address], @options[:proxy_port] ? @options[:proxy_port] : 80)
|
37
|
+
else
|
38
|
+
http_class = Net::HTTP
|
39
|
+
end
|
40
|
+
http_conn = http_class.new(uri.host, uri.port)
|
41
|
+
http_conn.use_ssl = @options[:use_ssl]
|
42
|
+
http_conn.verify_mode = @options[:ssl_verify_mode]
|
43
|
+
http_conn
|
44
|
+
end
|
45
|
+
|
46
|
+
def uri
|
47
|
+
uri = URI.parse(@options[:site])
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def store_cookies(response)
|
53
|
+
cookies = response.get_fields('set-cookie')
|
54
|
+
if cookies
|
55
|
+
cookies.each do |cookie|
|
56
|
+
data = CGI::Cookie.parse(cookie)
|
57
|
+
data.delete('Path')
|
58
|
+
@cookies.merge!(data)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def add_cookies(request)
|
64
|
+
cookie_array = @cookies.values.map { |cookie| cookie.to_s }
|
65
|
+
request.add_field('Cookie', cookie_array.join('; ')) if cookie_array.any?
|
66
|
+
request
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
module JIRA
|
3
|
+
|
4
|
+
class HTTPError < StandardError
|
5
|
+
extend Forwardable
|
6
|
+
|
7
|
+
def_instance_delegators :@response, :message, :code
|
8
|
+
attr_reader :response
|
9
|
+
|
10
|
+
def initialize(response)
|
11
|
+
@response = response
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'oauth'
|
2
|
+
require 'json'
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
module JIRA
|
6
|
+
class OauthClient < RequestClient
|
7
|
+
|
8
|
+
DEFAULT_OPTIONS = {
|
9
|
+
:signature_method => 'RSA-SHA1',
|
10
|
+
:request_token_path => "/plugins/servlet/oauth/request-token",
|
11
|
+
:authorize_path => "/plugins/servlet/oauth/authorize",
|
12
|
+
:access_token_path => "/plugins/servlet/oauth/access-token",
|
13
|
+
:private_key_file => "rsakey.pem",
|
14
|
+
:consumer_key => nil,
|
15
|
+
:consumer_secret => nil
|
16
|
+
}
|
17
|
+
|
18
|
+
# This exception is thrown when the client is used before the OAuth access token
|
19
|
+
# has been initialized.
|
20
|
+
class UninitializedAccessTokenError < StandardError
|
21
|
+
def message
|
22
|
+
"init_access_token must be called before using the client"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
extend Forwardable
|
27
|
+
|
28
|
+
attr_accessor :consumer
|
29
|
+
attr_reader :options
|
30
|
+
|
31
|
+
def_instance_delegators :@consumer, :key, :secret, :get_request_token
|
32
|
+
|
33
|
+
def initialize(options)
|
34
|
+
@options = DEFAULT_OPTIONS.merge(options)
|
35
|
+
@consumer = init_oauth_consumer(@options)
|
36
|
+
end
|
37
|
+
|
38
|
+
def init_oauth_consumer(options)
|
39
|
+
@options[:request_token_path] = @options[:context_path] + @options[:request_token_path]
|
40
|
+
@options[:authorize_path] = @options[:context_path] + @options[:authorize_path]
|
41
|
+
@options[:access_token_path] = @options[:context_path] + @options[:access_token_path]
|
42
|
+
OAuth::Consumer.new(@options[:consumer_key],@options[:consumer_secret],@options)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Returns the current request token if it is set, else it creates
|
46
|
+
# and sets a new token.
|
47
|
+
def request_token
|
48
|
+
@request_token ||= get_request_token
|
49
|
+
end
|
50
|
+
|
51
|
+
# Sets the request token from a given token and secret.
|
52
|
+
def set_request_token(token, secret)
|
53
|
+
@request_token = OAuth::RequestToken.new(@consumer, token, secret)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Initialises and returns a new access token from the params hash
|
57
|
+
# returned by the OAuth transaction.
|
58
|
+
def init_access_token(params)
|
59
|
+
@access_token = request_token.get_access_token(params)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Sets the access token from a preexisting token and secret.
|
63
|
+
def set_access_token(token, secret)
|
64
|
+
@access_token = OAuth::AccessToken.new(@consumer, token, secret)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns the current access token. Raises an
|
68
|
+
# JIRA::Client::UninitializedAccessTokenError exception if it is not set.
|
69
|
+
def access_token
|
70
|
+
raise UninitializedAccessTokenError.new unless @access_token
|
71
|
+
@access_token
|
72
|
+
end
|
73
|
+
|
74
|
+
def make_request(http_method, path, body='', headers={})
|
75
|
+
case http_method
|
76
|
+
when :delete, :get, :head
|
77
|
+
response = access_token.send http_method, path, headers
|
78
|
+
when :post, :put
|
79
|
+
response = access_token.send http_method, path, body, headers
|
80
|
+
end
|
81
|
+
response
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
data/lib/jira/railtie.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'oauth'
|
2
|
+
require 'json'
|
3
|
+
require 'net/https'
|
4
|
+
|
5
|
+
module JIRA
|
6
|
+
class RequestClient
|
7
|
+
|
8
|
+
# Returns the response if the request was successful (HTTP::2xx) and
|
9
|
+
# raises a JIRA::HTTPError if it was not successful, with the response
|
10
|
+
# attached.
|
11
|
+
|
12
|
+
def request(*args)
|
13
|
+
response = make_request(*args)
|
14
|
+
raise HTTPError.new(response) unless response.kind_of?(Net::HTTPSuccess)
|
15
|
+
response
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module JIRA
|
2
|
+
module Resource
|
3
|
+
class FilterFactory < JIRA::BaseFactory # :nodoc:
|
4
|
+
end
|
5
|
+
|
6
|
+
class Filter < JIRA::Base
|
7
|
+
has_one :owner, :class => JIRA::Resource::User
|
8
|
+
|
9
|
+
# Returns all the issues for this filter
|
10
|
+
def issues
|
11
|
+
Issue.jql(self.client, self.jql)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
|
3
|
+
module JIRA
|
4
|
+
module Resource
|
5
|
+
|
6
|
+
class IssueFactory < JIRA::BaseFactory # :nodoc:
|
7
|
+
end
|
8
|
+
|
9
|
+
class Issue < JIRA::Base
|
10
|
+
|
11
|
+
has_one :reporter, :class => JIRA::Resource::User,
|
12
|
+
:nested_under => 'fields'
|
13
|
+
has_one :assignee, :class => JIRA::Resource::User,
|
14
|
+
:nested_under => 'fields'
|
15
|
+
has_one :project, :nested_under => 'fields'
|
16
|
+
|
17
|
+
has_one :issuetype, :nested_under => 'fields'
|
18
|
+
|
19
|
+
has_one :priority, :nested_under => 'fields'
|
20
|
+
|
21
|
+
has_one :status, :nested_under => 'fields'
|
22
|
+
|
23
|
+
has_many :transitions
|
24
|
+
|
25
|
+
has_many :components, :nested_under => 'fields'
|
26
|
+
|
27
|
+
has_many :comments, :nested_under => ['fields','comment']
|
28
|
+
|
29
|
+
has_many :attachments, :nested_under => 'fields',
|
30
|
+
:attribute_key => 'attachment'
|
31
|
+
|
32
|
+
has_many :versions, :nested_under => 'fields'
|
33
|
+
|
34
|
+
has_many :worklogs, :nested_under => ['fields','worklog']
|
35
|
+
|
36
|
+
def self.all(client)
|
37
|
+
response = client.get(
|
38
|
+
client.options[:rest_base_path] + "/search",
|
39
|
+
:expand => 'transitions.fields'
|
40
|
+
)
|
41
|
+
json = parse_json(response.body)
|
42
|
+
json['issues'].map do |issue|
|
43
|
+
client.Issue.build(issue)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.jql(client, jql, fields = nil)
|
48
|
+
url = client.options[:rest_base_path] + "/search?jql=" + CGI.escape(jql)
|
49
|
+
url += CGI.escape("&fields=#{fields.join(",")}") if fields
|
50
|
+
response = client.get(url)
|
51
|
+
json = parse_json(response.body)
|
52
|
+
json['issues'].map do |issue|
|
53
|
+
client.Issue.build(issue)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def respond_to?(method_name)
|
58
|
+
if attrs.keys.include?('fields') && attrs['fields'].keys.include?(method_name.to_s)
|
59
|
+
true
|
60
|
+
else
|
61
|
+
super(method_name)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def method_missing(method_name, *args, &block)
|
66
|
+
if attrs.keys.include?('fields') && attrs['fields'].keys.include?(method_name.to_s)
|
67
|
+
attrs['fields'][method_name.to_s]
|
68
|
+
else
|
69
|
+
super(method_name)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module JIRA
|
2
|
+
module Resource
|
3
|
+
|
4
|
+
class ProjectFactory < JIRA::BaseFactory # :nodoc:
|
5
|
+
end
|
6
|
+
|
7
|
+
class Project < JIRA::Base
|
8
|
+
|
9
|
+
has_one :lead, :class => JIRA::Resource::User
|
10
|
+
has_many :components
|
11
|
+
has_many :issuetypes, :attribute_key => 'issueTypes'
|
12
|
+
has_many :versions
|
13
|
+
|
14
|
+
def self.key_attribute
|
15
|
+
:key
|
16
|
+
end
|
17
|
+
|
18
|
+
# Returns all the issues for this project
|
19
|
+
def issues(options={})
|
20
|
+
search_url = client.options[:rest_base_path] + '/search'
|
21
|
+
query_params = {:jql => "project=\"#{key}\""}
|
22
|
+
query_params.update Base.query_params_for_search(options)
|
23
|
+
response = client.get(url_with_query_params(search_url, query_params))
|
24
|
+
json = self.class.parse_json(response.body)
|
25
|
+
json['issues'].map do |issue|
|
26
|
+
client.Issue.build(issue)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module JIRA
|
2
|
+
module Resource
|
3
|
+
|
4
|
+
class TransitionFactory < JIRA::BaseFactory # :nodoc:
|
5
|
+
end
|
6
|
+
|
7
|
+
class Transition < JIRA::Base
|
8
|
+
has_one :to, :class => JIRA::Resource::Status
|
9
|
+
belongs_to :issue
|
10
|
+
|
11
|
+
nested_collections true
|
12
|
+
|
13
|
+
def self.endpoint_name
|
14
|
+
'transitions'
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.all(client, options = {})
|
18
|
+
issue = options[:issue]
|
19
|
+
unless issue
|
20
|
+
raise ArgumentError.new("parent issue is required")
|
21
|
+
end
|
22
|
+
|
23
|
+
path = "#{issue.self}/#{endpoint_name}?expand=transitions.fields"
|
24
|
+
response = client.get(path)
|
25
|
+
json = parse_json(response.body)
|
26
|
+
json['transitions'].map do |transition|
|
27
|
+
issue.transitions.build(transition)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module JIRA
|
2
|
+
module Resource
|
3
|
+
|
4
|
+
class UserFactory < JIRA::BaseFactory # :nodoc:
|
5
|
+
end
|
6
|
+
|
7
|
+
class User < JIRA::Base
|
8
|
+
def self.singular_path(client, key, prefix = '/')
|
9
|
+
collection_path(client, prefix) + '?username=' + key
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module JIRA
|
2
|
+
module Resource
|
3
|
+
|
4
|
+
class WorklogFactory < JIRA::BaseFactory # :nodoc:
|
5
|
+
end
|
6
|
+
|
7
|
+
class Worklog < JIRA::Base
|
8
|
+
has_one :author, :class => JIRA::Resource::User
|
9
|
+
has_one :update_author, :class => JIRA::Resource::User,
|
10
|
+
:attribute_key => "updateAuthor"
|
11
|
+
belongs_to :issue
|
12
|
+
nested_collections true
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
data/lib/jira/tasks.rb
ADDED
File without changes
|
data/lib/jira/version.rb
ADDED
data/lib/jira.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
$: << File.expand_path(File.dirname(__FILE__))
|
2
|
+
|
3
|
+
require 'active_support/inflector'
|
4
|
+
ActiveSupport::Inflector.inflections do |inflector|
|
5
|
+
inflector.singular 'status', 'status'
|
6
|
+
end
|
7
|
+
|
8
|
+
require 'jira/base'
|
9
|
+
require 'jira/base_factory'
|
10
|
+
require 'jira/has_many_proxy'
|
11
|
+
require 'jira/http_error'
|
12
|
+
|
13
|
+
require 'jira/resource/user'
|
14
|
+
require 'jira/resource/attachment'
|
15
|
+
require 'jira/resource/component'
|
16
|
+
require 'jira/resource/issuetype'
|
17
|
+
require 'jira/resource/version'
|
18
|
+
require 'jira/resource/status'
|
19
|
+
require 'jira/resource/transition'
|
20
|
+
require 'jira/resource/project'
|
21
|
+
require 'jira/resource/priority'
|
22
|
+
require 'jira/resource/comment'
|
23
|
+
require 'jira/resource/worklog'
|
24
|
+
require 'jira/resource/issue'
|
25
|
+
require 'jira/resource/filter'
|
26
|
+
require 'jira/resource/field'
|
27
|
+
|
28
|
+
require 'jira/request_client'
|
29
|
+
require 'jira/oauth_client'
|
30
|
+
require 'jira/http_client'
|
31
|
+
require 'jira/client'
|
32
|
+
|
33
|
+
require 'jira/railtie' if defined?(Rails)
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
3
|
+
namespace :jira do
|
4
|
+
desc "Generate a consumer key for your application"
|
5
|
+
task :generate_consumer_key do
|
6
|
+
key = SecureRandom.hex(16)
|
7
|
+
puts "You can use this as your consumer key: #{key}"
|
8
|
+
end
|
9
|
+
|
10
|
+
desc "Run the system call to generate a RSA public certificate"
|
11
|
+
task :generate_public_cert do
|
12
|
+
puts "Executing 'openssl req -x509 -nodes -newkey rsa:1024 -sha1 -keyout rsakey.pem -out rsacert.pem'"
|
13
|
+
system('openssl req -x509 -subj "/C=US/ST=New York/L=New York/O=SUMO Heavy Industries/CN=www.sumoheavy.com" -nodes -newkey rsa:1024 -sha1 -keyout rsakey.pem -out rsacert.pem')
|
14
|
+
puts "Done. The RSA-SHA1 private keyfile is in the current directory: \'rsakey.pem\'."
|
15
|
+
puts "You will need to copy the following certificate into your application link configuration in Jira:"
|
16
|
+
system("cat rsacert.pem")
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe JIRA::Resource::Attachment do
|
4
|
+
|
5
|
+
with_each_client do |site_url, client|
|
6
|
+
let(:client) { client }
|
7
|
+
let(:site_url) { site_url }
|
8
|
+
|
9
|
+
let(:key) { "10000" }
|
10
|
+
|
11
|
+
let(:expected_attributes) do
|
12
|
+
{
|
13
|
+
'self' => "http://localhost:2990/jira/rest/api/2/attachment/10000",
|
14
|
+
'size' => 15360,
|
15
|
+
'filename' => "ballmer.png"
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
it_should_behave_like "a resource"
|
20
|
+
it_should_behave_like "a resource with a singular GET endpoint"
|
21
|
+
it_should_behave_like "a resource with a DELETE endpoint"
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe JIRA::Resource::Comment do
|
4
|
+
|
5
|
+
with_each_client do |site_url, client|
|
6
|
+
let(:client) { client }
|
7
|
+
let(:site_url) { site_url }
|
8
|
+
|
9
|
+
let(:key) { "10000" }
|
10
|
+
|
11
|
+
let(:target) { JIRA::Resource::Comment.new(client, :attrs => {'id' => '99999'}, :issue_id => '54321') }
|
12
|
+
|
13
|
+
let(:expected_collection_length) { 2 }
|
14
|
+
|
15
|
+
let(:belongs_to) {
|
16
|
+
JIRA::Resource::Issue.new(client, :attrs => {
|
17
|
+
'id' => '10002',
|
18
|
+
'fields' => {
|
19
|
+
'comment' => {'comments' => []}
|
20
|
+
}
|
21
|
+
})
|
22
|
+
}
|
23
|
+
|
24
|
+
let(:expected_attributes) do
|
25
|
+
{
|
26
|
+
'self' => "http://localhost:2990/jira/rest/api/2/issue/10002/comment/10000",
|
27
|
+
'id' => key,
|
28
|
+
'body' => "This is a comment. Creative."
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
let(:attributes_for_post) {
|
33
|
+
{ "body" => "new comment" }
|
34
|
+
}
|
35
|
+
let(:expected_attributes_from_post) {
|
36
|
+
{ "id" => "10001", "body" => "new comment"}
|
37
|
+
}
|
38
|
+
|
39
|
+
let(:attributes_for_put) {
|
40
|
+
{"body" => "new body"}
|
41
|
+
}
|
42
|
+
let(:expected_attributes_from_put) {
|
43
|
+
{ "id" => "10000", "body" => "new body" }
|
44
|
+
}
|
45
|
+
|
46
|
+
it_should_behave_like "a resource"
|
47
|
+
it_should_behave_like "a resource with a collection GET endpoint"
|
48
|
+
it_should_behave_like "a resource with a singular GET endpoint"
|
49
|
+
it_should_behave_like "a resource with a DELETE endpoint"
|
50
|
+
it_should_behave_like "a resource with a POST endpoint"
|
51
|
+
it_should_behave_like "a resource with a PUT endpoint"
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|