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.
Files changed (107) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.travis.yml +6 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +46 -0
  6. data/README.rdoc +309 -0
  7. data/Rakefile +28 -0
  8. data/example.rb +119 -0
  9. data/http-basic-example.rb +112 -0
  10. data/jira-ruby-dmg.gemspec +28 -0
  11. data/lib/jira/base.rb +497 -0
  12. data/lib/jira/base_factory.rb +49 -0
  13. data/lib/jira/client.rb +165 -0
  14. data/lib/jira/has_many_proxy.rb +43 -0
  15. data/lib/jira/http_client.rb +69 -0
  16. data/lib/jira/http_error.rb +16 -0
  17. data/lib/jira/oauth_client.rb +84 -0
  18. data/lib/jira/railtie.rb +10 -0
  19. data/lib/jira/request_client.rb +18 -0
  20. data/lib/jira/resource/attachment.rb +12 -0
  21. data/lib/jira/resource/comment.rb +14 -0
  22. data/lib/jira/resource/component.rb +10 -0
  23. data/lib/jira/resource/field.rb +10 -0
  24. data/lib/jira/resource/filter.rb +15 -0
  25. data/lib/jira/resource/issue.rb +76 -0
  26. data/lib/jira/resource/issuetype.rb +10 -0
  27. data/lib/jira/resource/priority.rb +10 -0
  28. data/lib/jira/resource/project.rb +31 -0
  29. data/lib/jira/resource/status.rb +10 -0
  30. data/lib/jira/resource/transition.rb +33 -0
  31. data/lib/jira/resource/user.rb +14 -0
  32. data/lib/jira/resource/version.rb +10 -0
  33. data/lib/jira/resource/worklog.rb +16 -0
  34. data/lib/jira/tasks.rb +0 -0
  35. data/lib/jira/version.rb +3 -0
  36. data/lib/jira.rb +33 -0
  37. data/lib/tasks/generate.rake +18 -0
  38. data/spec/integration/attachment_spec.rb +23 -0
  39. data/spec/integration/comment_spec.rb +55 -0
  40. data/spec/integration/component_spec.rb +42 -0
  41. data/spec/integration/field_spec.rb +35 -0
  42. data/spec/integration/issue_spec.rb +94 -0
  43. data/spec/integration/issuetype_spec.rb +26 -0
  44. data/spec/integration/priority_spec.rb +27 -0
  45. data/spec/integration/project_spec.rb +56 -0
  46. data/spec/integration/status_spec.rb +27 -0
  47. data/spec/integration/transition_spec.rb +52 -0
  48. data/spec/integration/user_spec.rb +25 -0
  49. data/spec/integration/version_spec.rb +43 -0
  50. data/spec/integration/worklog_spec.rb +55 -0
  51. data/spec/jira/base_factory_spec.rb +46 -0
  52. data/spec/jira/base_spec.rb +586 -0
  53. data/spec/jira/client_spec.rb +188 -0
  54. data/spec/jira/has_many_proxy_spec.rb +45 -0
  55. data/spec/jira/http_client_spec.rb +109 -0
  56. data/spec/jira/http_error_spec.rb +25 -0
  57. data/spec/jira/oauth_client_spec.rb +111 -0
  58. data/spec/jira/request_client_spec.rb +14 -0
  59. data/spec/jira/resource/attachment_spec.rb +20 -0
  60. data/spec/jira/resource/filter_spec.rb +97 -0
  61. data/spec/jira/resource/issue_spec.rb +107 -0
  62. data/spec/jira/resource/project_factory_spec.rb +13 -0
  63. data/spec/jira/resource/project_spec.rb +70 -0
  64. data/spec/jira/resource/worklog_spec.rb +24 -0
  65. data/spec/mock_responses/attachment/10000.json +20 -0
  66. data/spec/mock_responses/component/10000.invalid.put.json +5 -0
  67. data/spec/mock_responses/component/10000.json +39 -0
  68. data/spec/mock_responses/component/10000.put.json +39 -0
  69. data/spec/mock_responses/component.post.json +28 -0
  70. data/spec/mock_responses/field/1.json +15 -0
  71. data/spec/mock_responses/field.json +32 -0
  72. data/spec/mock_responses/issue/10002/comment/10000.json +29 -0
  73. data/spec/mock_responses/issue/10002/comment/10000.put.json +29 -0
  74. data/spec/mock_responses/issue/10002/comment.json +65 -0
  75. data/spec/mock_responses/issue/10002/comment.post.json +29 -0
  76. data/spec/mock_responses/issue/10002/transitions.json +49 -0
  77. data/spec/mock_responses/issue/10002/transitions.post.json +1 -0
  78. data/spec/mock_responses/issue/10002/worklog/10000.json +31 -0
  79. data/spec/mock_responses/issue/10002/worklog/10000.put.json +30 -0
  80. data/spec/mock_responses/issue/10002/worklog.json +98 -0
  81. data/spec/mock_responses/issue/10002/worklog.post.json +30 -0
  82. data/spec/mock_responses/issue/10002.invalid.put.json +6 -0
  83. data/spec/mock_responses/issue/10002.json +126 -0
  84. data/spec/mock_responses/issue/10002.put.missing_field_update.json +6 -0
  85. data/spec/mock_responses/issue.json +1108 -0
  86. data/spec/mock_responses/issue.post.json +5 -0
  87. data/spec/mock_responses/issuetype/5.json +8 -0
  88. data/spec/mock_responses/issuetype.json +42 -0
  89. data/spec/mock_responses/priority/1.json +8 -0
  90. data/spec/mock_responses/priority.json +42 -0
  91. data/spec/mock_responses/project/SAMPLEPROJECT.issues.json +1108 -0
  92. data/spec/mock_responses/project/SAMPLEPROJECT.json +84 -0
  93. data/spec/mock_responses/project.json +12 -0
  94. data/spec/mock_responses/status/1.json +7 -0
  95. data/spec/mock_responses/status.json +37 -0
  96. data/spec/mock_responses/user_username=admin.json +17 -0
  97. data/spec/mock_responses/version/10000.invalid.put.json +5 -0
  98. data/spec/mock_responses/version/10000.json +11 -0
  99. data/spec/mock_responses/version/10000.put.json +7 -0
  100. data/spec/mock_responses/version.post.json +7 -0
  101. data/spec/spec_helper.rb +22 -0
  102. data/spec/support/clients_helper.rb +16 -0
  103. data/spec/support/matchers/have_attributes.rb +11 -0
  104. data/spec/support/matchers/have_many.rb +9 -0
  105. data/spec/support/matchers/have_one.rb +5 -0
  106. data/spec/support/shared_examples/integration.rb +190 -0
  107. metadata +301 -0
@@ -0,0 +1,188 @@
1
+ require 'spec_helper'
2
+
3
+ describe JIRA::Client do
4
+
5
+ let(:oauth_client) do
6
+ JIRA::Client.new({ :consumer_key => 'foo', :consumer_secret => 'bar' })
7
+ end
8
+
9
+ let(:basic_client) do
10
+ JIRA::Client.new({ :username => 'foo', :password => 'bar', :auth_type => :basic })
11
+ end
12
+
13
+ let(:clients) { [oauth_client, basic_client] }
14
+
15
+ let(:response) do
16
+ response = double("response")
17
+ response.stub(:kind_of?).with(Net::HTTPSuccess).and_return(true)
18
+ response
19
+ end
20
+
21
+ let(:headers) { {'Accept' => 'application/json'} }
22
+ let(:content_type_header) { {'Content-Type' => 'application/json'} }
23
+ let(:merged_headers) { headers.merge(content_type_header) }
24
+
25
+ it "creates an instance" do
26
+ clients.each {|client| client.class.should == JIRA::Client }
27
+ end
28
+
29
+ it "allows the overriding of some options" do
30
+ client = JIRA::Client.new({:consumer_key => 'foo', :consumer_secret => 'bar', :site => 'http://foo.com/'})
31
+ client.options[:site].should == 'http://foo.com/'
32
+ JIRA::Client::DEFAULT_OPTIONS[:site].should_not == 'http://foo.com/'
33
+ end
34
+
35
+ it "prepends the context path to the rest base path" do
36
+ options = [:rest_base_path]
37
+ defaults = JIRA::Client::DEFAULT_OPTIONS
38
+ options.each do |key|
39
+ clients.each { |client| client.options[key].should == defaults[:context_path] + defaults[key] }
40
+ end
41
+ end
42
+
43
+ # To avoid having to validate options after initialisation, e.g. setting
44
+ # client.options[:invalid] = 'foo'
45
+ it "freezes the options" do
46
+ clients.each { |client| client.options.should be_frozen }
47
+ end
48
+
49
+ it "merges headers" do
50
+ clients.each { |client| client.send(:merge_default_headers, {}).should == {'Accept' => 'application/json'} }
51
+ end
52
+
53
+ describe "creates instances of request clients" do
54
+ specify "that are of the correct class" do
55
+ oauth_client.request_client.class.should == JIRA::OauthClient
56
+ basic_client.request_client.class.should == JIRA::HttpClient
57
+ end
58
+
59
+ specify "which have a corresponding auth type option" do
60
+ oauth_client.options[:auth_type].should == :oauth
61
+ basic_client.options[:auth_type].should == :basic
62
+ end
63
+
64
+ describe "like oauth" do
65
+
66
+ it "allows setting an access token" do
67
+ token = double()
68
+ OAuth::AccessToken.should_receive(:new).with(oauth_client.consumer, 'foo', 'bar').and_return(token)
69
+ access_token = oauth_client.set_access_token('foo', 'bar')
70
+
71
+ access_token.should == token
72
+ oauth_client.access_token.should == token
73
+ end
74
+
75
+ it "allows initializing the access token" do
76
+ request_token = OAuth::RequestToken.new(oauth_client.consumer)
77
+ oauth_client.consumer.stub(:get_request_token => request_token)
78
+ mock_access_token = double()
79
+ request_token.should_receive(:get_access_token).with(:oauth_verifier => 'abc123').and_return(mock_access_token)
80
+ oauth_client.init_access_token(:oauth_verifier => 'abc123')
81
+ oauth_client.access_token.should == mock_access_token
82
+ end
83
+
84
+ specify "that has specific default options" do
85
+ options = [:signature_method, :private_key_file]
86
+ options.each do |key|
87
+ oauth_client.options[key].should == JIRA::Client::DEFAULT_OPTIONS[key]
88
+ end
89
+ end
90
+ end
91
+
92
+ describe "like basic http" do
93
+ it "sets the username and password" do
94
+ basic_client.options[:username].should == 'foo'
95
+ basic_client.options[:password].should == 'bar'
96
+ end
97
+ end
98
+ end
99
+
100
+ describe "has http methods" do
101
+ before do
102
+ oauth_client.set_access_token("foo", "bar")
103
+ end
104
+
105
+ specify "that merge default headers" do
106
+ # stubbed response for generic client request method
107
+ oauth_client.should_receive(:request).exactly(5).times.and_return(response)
108
+ basic_client.should_receive(:request).exactly(5).times.and_return(response)
109
+
110
+ # response for merging headers for http methods with no body
111
+ oauth_client.should_receive(:merge_default_headers).exactly(3).times.with({})
112
+ basic_client.should_receive(:merge_default_headers).exactly(3).times.with({})
113
+
114
+ # response for merging headers for http methods with body
115
+ oauth_client.should_receive(:merge_default_headers).exactly(2).times.with(content_type_header)
116
+ basic_client.should_receive(:merge_default_headers).exactly(2).times.with(content_type_header)
117
+
118
+ [:delete, :get, :head].each do |method|
119
+ oauth_client.send(method, '/path', {})
120
+ basic_client.send(method, '/path', {})
121
+ end
122
+
123
+ [:post, :put].each do |method|
124
+ oauth_client.send(method, '/path', '', content_type_header)
125
+ basic_client.send(method, '/path', '', content_type_header)
126
+ end
127
+ end
128
+
129
+ specify "that call the generic request method" do
130
+ [:delete, :get, :head].each do |method|
131
+ oauth_client.should_receive(:request).with(method, '/path', nil, headers).and_return(response)
132
+ basic_client.should_receive(:request).with(method, '/path', nil, headers).and_return(response)
133
+ oauth_client.send(method, '/path', {})
134
+ basic_client.send(method, '/path', {})
135
+ end
136
+
137
+ [:post, :put].each do |method|
138
+ oauth_client.should_receive(:request).with(method, '/path', '', merged_headers)
139
+ basic_client.should_receive(:request).with(method, '/path', '', merged_headers)
140
+ oauth_client.send(method, '/path', '', {})
141
+ basic_client.send(method, '/path', '', {})
142
+ end
143
+ end
144
+
145
+ describe "that call a oauth client" do
146
+ specify "which makes a request" do
147
+ [:delete, :get, :head].each do |method|
148
+ oauth_client.request_client.should_receive(:make_request).with(method, '/path', nil, headers).and_return(response)
149
+ oauth_client.send(method, '/path', {})
150
+ end
151
+ [:post, :put].each do |method|
152
+ oauth_client.request_client.should_receive(:make_request).with(method, '/path', '', merged_headers).and_return(response)
153
+ oauth_client.send(method, '/path', '', {})
154
+ end
155
+ end
156
+ end
157
+
158
+ describe "that call a http client" do
159
+ it "which makes a request" do
160
+ [:delete, :get, :head].each do |method|
161
+ basic_client.request_client.should_receive(:make_request).with(method, '/path', nil, headers).and_return(response)
162
+ basic_client.send(method, '/path', headers)
163
+ end
164
+ [:post, :put].each do |method|
165
+ basic_client.request_client.should_receive(:make_request).with(method, '/path', '', merged_headers).and_return(response)
166
+ basic_client.send(method, '/path', '', headers)
167
+ end
168
+ end
169
+ end
170
+ end
171
+
172
+ describe "Resource Factories" do
173
+ it "gets all projects" do
174
+ JIRA::Resource::Project.should_receive(:all).with(oauth_client).and_return([])
175
+ JIRA::Resource::Project.should_receive(:all).with(basic_client).and_return([])
176
+ oauth_client.Project.all.should == []
177
+ basic_client.Project.all.should == []
178
+ end
179
+
180
+ it "finds a single project" do
181
+ find_result = double()
182
+ JIRA::Resource::Project.should_receive(:find).with(oauth_client, '123').and_return(find_result)
183
+ JIRA::Resource::Project.should_receive(:find).with(basic_client, '123').and_return(find_result)
184
+ oauth_client.Project.find('123').should == find_result
185
+ basic_client.Project.find('123').should == find_result
186
+ end
187
+ end
188
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe JIRA::HasManyProxy do
4
+
5
+ class Foo ; end
6
+
7
+ subject { JIRA::HasManyProxy.new(parent, Foo, collection) }
8
+
9
+ let(:parent) { double("parent") }
10
+ let(:collection) { double("collection") }
11
+
12
+ it "has a target class" do
13
+ subject.target_class.should == Foo
14
+ end
15
+
16
+ it "has a parent" do
17
+ subject.parent.should == parent
18
+ end
19
+
20
+ it "has a collection" do
21
+ subject.collection.should == collection
22
+ end
23
+
24
+ it "can build a new instance" do
25
+ client = double('client')
26
+ foo = double('foo')
27
+ parent.stub(:client => client, :to_sym => :parent)
28
+ Foo.should_receive(:new).with(client, :attrs => {'foo' => 'bar'}, :parent => parent).and_return(foo)
29
+ collection.should_receive(:<<).with(foo)
30
+ subject.build('foo' => 'bar').should == foo
31
+ end
32
+
33
+ it "can get all the instances" do
34
+ foo = double('foo')
35
+ client = double('client')
36
+ parent.stub(:client => client, :to_sym => :parent)
37
+ Foo.should_receive(:all).with(client, :parent => parent).and_return(foo)
38
+ subject.all.should == foo
39
+ end
40
+
41
+ it "delegates missing methods to the collection" do
42
+ collection.should_receive(:missing_method)
43
+ subject.missing_method
44
+ end
45
+ end
@@ -0,0 +1,109 @@
1
+ require 'spec_helper'
2
+
3
+ describe JIRA::HttpClient do
4
+
5
+ let(:basic_client) do
6
+ options = JIRA::Client::DEFAULT_OPTIONS.merge(JIRA::HttpClient::DEFAULT_OPTIONS)
7
+ JIRA::HttpClient.new(options)
8
+ end
9
+
10
+ let(:basic_cookie_client) do
11
+ options = JIRA::Client::DEFAULT_OPTIONS.merge(JIRA::HttpClient::DEFAULT_OPTIONS).merge(:use_cookies => true)
12
+ JIRA::HttpClient.new(options)
13
+ end
14
+
15
+ let(:response) do
16
+ response = double("response")
17
+ response.stub(:kind_of?).with(Net::HTTPSuccess).and_return(true)
18
+ response
19
+ end
20
+
21
+ let(:cookie_response) do
22
+ response = double("response")
23
+ response.stub(:kind_of?).with(Net::HTTPSuccess).and_return(true)
24
+ response
25
+ end
26
+
27
+ it "creates an instance of Net:HTTP for a basic auth client" do
28
+ basic_client.basic_auth_http_conn.class.should == Net::HTTP
29
+ end
30
+
31
+ it "responds to the http methods" do
32
+ body = ''
33
+ headers = double()
34
+ basic_auth_http_conn = double()
35
+ request = double()
36
+ basic_client.stub(:basic_auth_http_conn => basic_auth_http_conn)
37
+ request.should_receive(:basic_auth).with(basic_client.options[:username], basic_client.options[:password]).exactly(5).times.and_return(request)
38
+ basic_auth_http_conn.should_receive(:request).exactly(5).times.with(request).and_return(response)
39
+ [:delete, :get, :head].each do |method|
40
+ Net::HTTP.const_get(method.to_s.capitalize).should_receive(:new).with('/path', headers).and_return(request)
41
+ basic_client.make_request(method, '/path', nil, headers).should == response
42
+ end
43
+ [:post, :put].each do |method|
44
+ Net::HTTP.const_get(method.to_s.capitalize).should_receive(:new).with('/path', headers).and_return(request)
45
+ request.should_receive(:body=).with(body).and_return(request)
46
+ basic_client.make_request(method, '/path', body, headers).should == response
47
+ end
48
+ end
49
+
50
+ it "gets and sets cookies" do
51
+ body = ''
52
+ headers = double()
53
+ basic_auth_http_conn = double()
54
+ request = double()
55
+ basic_cookie_client.stub(:basic_auth_http_conn => basic_auth_http_conn)
56
+ request.should_receive(:basic_auth).with(basic_cookie_client.options[:username], basic_cookie_client.options[:password]).exactly(5).times.and_return(request)
57
+ cookie_response.should_receive(:get_fields).with('set-cookie').exactly(5).times
58
+ basic_auth_http_conn.should_receive(:request).exactly(5).times.with(request).and_return(cookie_response)
59
+ [:delete, :get, :head].each do |method|
60
+ Net::HTTP.const_get(method.to_s.capitalize).should_receive(:new).with('/path', headers).and_return(request)
61
+ basic_cookie_client.make_request(method, '/path', nil, headers).should == cookie_response
62
+ end
63
+ [:post, :put].each do |method|
64
+ Net::HTTP.const_get(method.to_s.capitalize).should_receive(:new).with('/path', headers).and_return(request)
65
+ request.should_receive(:body=).with(body).and_return(request)
66
+ basic_cookie_client.make_request(method, '/path', body, headers).should == cookie_response
67
+ end
68
+ end
69
+
70
+
71
+ it "performs a basic http client request" do
72
+ body = nil
73
+ headers = double()
74
+ basic_auth_http_conn = double()
75
+ http_request = double()
76
+ Net::HTTP::Get.should_receive(:new).with('/foo', headers).and_return(http_request)
77
+
78
+ basic_auth_http_conn.should_receive(:request).with(http_request).and_return(response)
79
+ http_request.should_receive(:basic_auth).with(basic_client.options[:username], basic_client.options[:password]).and_return(http_request)
80
+ basic_client.stub(:basic_auth_http_conn => basic_auth_http_conn)
81
+ basic_client.make_request(:get, '/foo', body, headers)
82
+ end
83
+
84
+ it "returns a URI" do
85
+ uri = URI.parse(basic_client.options[:site])
86
+ basic_client.uri.should == uri
87
+ end
88
+
89
+ it "sets up a http connection with options" do
90
+ http_conn = double()
91
+ uri = double()
92
+ host = double()
93
+ port = double()
94
+ uri.should_receive(:host).and_return(host)
95
+ uri.should_receive(:port).and_return(port)
96
+ Net::HTTP.should_receive(:new).with(host, port).and_return(http_conn)
97
+ http_conn.should_receive(:use_ssl=).with(basic_client.options[:use_ssl]).and_return(http_conn)
98
+ http_conn.should_receive(:verify_mode=).with(basic_client.options[:ssl_verify_mode]).and_return(http_conn)
99
+ basic_client.http_conn(uri).should == http_conn
100
+ end
101
+
102
+ it "returns a http connection" do
103
+ http_conn = double()
104
+ uri = double()
105
+ basic_client.should_receive(:uri).and_return(uri)
106
+ basic_client.should_receive(:http_conn).and_return(http_conn)
107
+ basic_client.basic_auth_http_conn.should == http_conn
108
+ end
109
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe JIRA::HTTPError do
4
+
5
+ let(:response) {
6
+ response = double("response")
7
+ response.stub(:code => 401)
8
+ response.stub(:message => "A MESSAGE WOO")
9
+ response
10
+ }
11
+ subject { described_class.new(response) }
12
+
13
+ it "takes the response object as an argument" do
14
+ subject.response.should == response
15
+ end
16
+
17
+ it "has a code method" do
18
+ subject.code.should == response.code
19
+ end
20
+
21
+ it "returns code and class from message" do
22
+ subject.message.should == response.message
23
+ end
24
+
25
+ end
@@ -0,0 +1,111 @@
1
+ require 'spec_helper'
2
+
3
+ describe JIRA::OauthClient do
4
+
5
+ let(:oauth_client) do
6
+ options = { :consumer_key => 'foo', :consumer_secret => 'bar' }
7
+ options = JIRA::Client::DEFAULT_OPTIONS.merge(options)
8
+ JIRA::OauthClient.new(options)
9
+ end
10
+
11
+ let(:response) do
12
+ response = double("response")
13
+ response.stub(:kind_of?).with(Net::HTTPSuccess).and_return(true)
14
+ response
15
+ end
16
+
17
+ describe "authenticating with oauth" do
18
+ it "prepends the context path to all authorization and rest paths" do
19
+ options = [:request_token_path, :authorize_path, :access_token_path]
20
+ defaults = JIRA::Client::DEFAULT_OPTIONS.merge(JIRA::OauthClient::DEFAULT_OPTIONS)
21
+ options.each do |key|
22
+ oauth_client.options[key].should == defaults[:context_path] + defaults[key]
23
+ end
24
+ end
25
+
26
+ it "creates a Oauth::Consumer on initialize" do
27
+ oauth_client.consumer.class.should == OAuth::Consumer
28
+ oauth_client.consumer.key.should == oauth_client.key
29
+ oauth_client.consumer.secret.should == oauth_client.secret
30
+ end
31
+
32
+ it "returns an OAuth request_token" do
33
+ # Cannot just check for method delegation as http connection will be attempted
34
+ request_token = OAuth::RequestToken.new(oauth_client.consumer)
35
+ oauth_client.consumer.stub(:get_request_token => request_token)
36
+ oauth_client.get_request_token.should == request_token
37
+ end
38
+
39
+ it "allows setting the request token" do
40
+ token = double()
41
+ OAuth::RequestToken.should_receive(:new).with(oauth_client.consumer, 'foo', 'bar').and_return(token)
42
+
43
+ request_token = oauth_client.set_request_token('foo', 'bar')
44
+
45
+ request_token.should == token
46
+ oauth_client.request_token.should == token
47
+ end
48
+
49
+ it "allows setting the consumer key" do
50
+ oauth_client.key.should == 'foo'
51
+ end
52
+
53
+ it "allows setting the consumer secret" do
54
+ oauth_client.secret.should == 'bar'
55
+ end
56
+
57
+ describe "the access token" do
58
+
59
+ it "initializes" do
60
+ request_token = OAuth::RequestToken.new(oauth_client.consumer)
61
+ oauth_client.consumer.stub(:get_request_token => request_token)
62
+ mock_access_token = double()
63
+ request_token.should_receive(:get_access_token).with(:oauth_verifier => 'abc123').and_return(mock_access_token)
64
+ oauth_client.init_access_token(:oauth_verifier => 'abc123')
65
+ oauth_client.access_token.should == mock_access_token
66
+ end
67
+
68
+ it "raises an exception when accessing without initialisation" do
69
+ expect {
70
+ oauth_client.access_token
71
+ }.to raise_exception(JIRA::OauthClient::UninitializedAccessTokenError,
72
+ "init_access_token must be called before using the client")
73
+ end
74
+
75
+ it "allows setting the access token" do
76
+ token = double()
77
+ OAuth::AccessToken.should_receive(:new).with(oauth_client.consumer, 'foo', 'bar').and_return(token)
78
+
79
+ access_token = oauth_client.set_access_token('foo', 'bar')
80
+
81
+ access_token.should == token
82
+ oauth_client.access_token.should == token
83
+ end
84
+ end
85
+
86
+ describe "http" do
87
+ it "responds to the http methods" do
88
+ headers = double()
89
+ mock_access_token = double()
90
+ oauth_client.stub(:access_token => mock_access_token)
91
+ [:delete, :get, :head].each do |method|
92
+ mock_access_token.should_receive(method).with('/path', headers).and_return(response)
93
+ oauth_client.make_request(method, '/path', '', headers)
94
+ end
95
+ [:post, :put].each do |method|
96
+ mock_access_token.should_receive(method).with('/path', '', headers).and_return(response)
97
+ oauth_client.make_request(method, '/path', '', headers)
98
+ end
99
+ end
100
+
101
+ it "performs a request" do
102
+ body = nil
103
+ headers = double()
104
+ access_token = double()
105
+ access_token.should_receive(:send).with(:get, '/foo', headers).and_return(response)
106
+ oauth_client.stub(:access_token => access_token)
107
+ oauth_client.request(:get, '/foo', body, headers)
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe JIRA::RequestClient do
4
+
5
+ it "raises an exception for non success responses" do
6
+ response = double()
7
+ response.stub(:kind_of?).with(Net::HTTPSuccess).and_return(false)
8
+ rc = JIRA::RequestClient.new
9
+ rc.should_receive(:make_request).with(:get, '/foo', '', {}).and_return(response)
10
+ expect {
11
+ rc.request(:get, '/foo', '', {})
12
+ }.to raise_exception(JIRA::HTTPError)
13
+ end
14
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe JIRA::Resource::Attachment do
4
+
5
+ let(:client) { double() }
6
+
7
+ describe "relationships" do
8
+ subject {
9
+ JIRA::Resource::Attachment.new(client, :attrs => {
10
+ 'author' => {'foo' => 'bar'}
11
+ })
12
+ }
13
+
14
+ it "has the correct relationships" do
15
+ subject.should have_one(:author, JIRA::Resource::User)
16
+ subject.author.foo.should == 'bar'
17
+ end
18
+ end
19
+
20
+ end
@@ -0,0 +1,97 @@
1
+ require 'spec_helper'
2
+
3
+ describe JIRA::Resource::Filter do
4
+ let(:client) do
5
+ client = double()
6
+ client.stub(:Issue) { JIRA::Resource::IssueFactory.new(self) }
7
+ client
8
+ end
9
+ let(:collection_path) { '/rest/api/2/filter' }
10
+ let(:jira_user) do
11
+ {
12
+ :self => "https://localhost/rest/api/2/user?username=ljharb",
13
+ :name => 'ljharb',
14
+ :avatarUrls => {
15
+ '16x16' => 'https://localhost/secure/useravatar?size=small&ownerId=ljharb&avatarId=1',
16
+ '48x48' => 'https://localhost/secure/useravatar?ownerId=ljharb&avatarId=1'
17
+ },
18
+ :displayName => 'Jordan Harband',
19
+ :active => true
20
+ }
21
+ end
22
+ let(:filter_attrs) do
23
+ {
24
+ :self => "https://localhost#{collection_path}/42",
25
+ :id => 42,
26
+ :name => 'Resolved Tickets',
27
+ :description => '',
28
+ :owner => jira_user,
29
+ :jql => '"Git Repository" ~ jira-ruby-dmg AND status = Resolved',
30
+ :viewUrl => 'https://localhost/secure/IssueNavigator.jspa?mode=hide&requestId=42',
31
+ :searchUrl => 'https://localhost/rest/api/2/search?jql=%22Git+Repository%22+~+jira-ruby-dmg+AND+status+%3D+Resolved',
32
+ :favourite => false,
33
+ :sharePermissions => [
34
+ {
35
+ :id => 123,
36
+ :type => 'global'
37
+ }
38
+ ],
39
+ :subscriptions => {
40
+ :size => 0,
41
+ :items => []
42
+ }
43
+ }
44
+ end
45
+ let(:filter_response) do
46
+ response = double()
47
+ response.stub(:body).and_return(filter_attrs.to_json)
48
+ response
49
+ end
50
+ let(:filter) do
51
+ client.should_receive(:get).with("#{collection_path}/42").and_return(filter_response)
52
+ JIRA::Resource::Filter.stub(:collection_path).and_return(collection_path)
53
+ JIRA::Resource::Filter.find(client, 42)
54
+ end
55
+ let(:jql_issue) do
56
+ {
57
+ :id => '663147',
58
+ :self => 'https://localhost/rest/api/2/issue/663147',
59
+ :key => "JIRARUBY-2386",
60
+ :fields => {
61
+ :reporter => jira_user,
62
+ :created => '2013-12-11T23:28:02.000+0000',
63
+ :assignee => jira_user
64
+ }
65
+ }
66
+ end
67
+ let(:jql_attrs) do
68
+ {
69
+ :startAt => 0,
70
+ :maxResults => 50,
71
+ :total => 2,
72
+ :issues => [jql_issue]
73
+ }
74
+ end
75
+ let(:issue_jql_response) do
76
+ response = double()
77
+ response.stub(:body).and_return(jql_attrs.to_json)
78
+ response
79
+ end
80
+
81
+ it "can be found by ID" do
82
+ expect(JSON.parse(filter.attrs.to_json)).to eql(JSON.parse(filter_attrs.to_json))
83
+ end
84
+
85
+ it "returns issues" do
86
+ expect(filter).to be_present
87
+ client.stub(:options) { { :rest_base_path => 'localhost' } }
88
+ client.should_receive(:get).
89
+ with("localhost/search?jql=#{CGI.escape(filter.jql)}").
90
+ and_return(issue_jql_response)
91
+ issues = filter.issues
92
+ expect(issues).to be_an(Array)
93
+ expect(issues.size).to eql(1)
94
+ expected_issue = client.Issue.build(JSON.parse(jql_issue.to_json))
95
+ expect(issues.first.attrs).to eql(expected_issue.attrs)
96
+ end
97
+ end