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,84 @@
|
|
1
|
+
{
|
2
|
+
"self": "http://localhost:2990/jira/rest/api/2/project/SAMPLEPROJECT",
|
3
|
+
"id": "10001",
|
4
|
+
"key": "SAMPLEPROJECT",
|
5
|
+
"lead": {
|
6
|
+
"self": "http://localhost:2990/jira/rest/api/2/user?username=admin",
|
7
|
+
"name": "admin",
|
8
|
+
"avatarUrls": {
|
9
|
+
"16x16": "http://localhost:2990/jira/secure/useravatar?size=small&avatarId=10122",
|
10
|
+
"48x48": "http://localhost:2990/jira/secure/useravatar?avatarId=10122"
|
11
|
+
},
|
12
|
+
"displayName": "admin",
|
13
|
+
"active": true
|
14
|
+
},
|
15
|
+
"components": [
|
16
|
+
{
|
17
|
+
"self": "http://localhost:2990/jira/rest/api/2/component/10001",
|
18
|
+
"id": "10001",
|
19
|
+
"name": "Jamflam",
|
20
|
+
"isAssigneeTypeValid": false
|
21
|
+
},
|
22
|
+
{
|
23
|
+
"self": "http://localhost:2990/jira/rest/api/2/component/10000",
|
24
|
+
"id": "10000",
|
25
|
+
"name": "Jammy",
|
26
|
+
"description": "Description!",
|
27
|
+
"isAssigneeTypeValid": false
|
28
|
+
}
|
29
|
+
],
|
30
|
+
"issueTypes": [
|
31
|
+
{
|
32
|
+
"self": "http://localhost:2990/jira/rest/api/2/issuetype/1",
|
33
|
+
"id": "1",
|
34
|
+
"description": "A problem which impairs or prevents the functions of the product.",
|
35
|
+
"iconUrl": "http://localhost:2990/jira/images/icons/bug.gif",
|
36
|
+
"name": "Bug",
|
37
|
+
"subtask": false
|
38
|
+
},
|
39
|
+
{
|
40
|
+
"self": "http://localhost:2990/jira/rest/api/2/issuetype/2",
|
41
|
+
"id": "2",
|
42
|
+
"description": "A new feature of the product, which has yet to be developed.",
|
43
|
+
"iconUrl": "http://localhost:2990/jira/images/icons/newfeature.gif",
|
44
|
+
"name": "New Feature",
|
45
|
+
"subtask": false
|
46
|
+
},
|
47
|
+
{
|
48
|
+
"self": "http://localhost:2990/jira/rest/api/2/issuetype/3",
|
49
|
+
"id": "3",
|
50
|
+
"description": "A task that needs to be done.",
|
51
|
+
"iconUrl": "http://localhost:2990/jira/images/icons/task.gif",
|
52
|
+
"name": "Task",
|
53
|
+
"subtask": false
|
54
|
+
},
|
55
|
+
{
|
56
|
+
"self": "http://localhost:2990/jira/rest/api/2/issuetype/4",
|
57
|
+
"id": "4",
|
58
|
+
"description": "An improvement or enhancement to an existing feature or task.",
|
59
|
+
"iconUrl": "http://localhost:2990/jira/images/icons/improvement.gif",
|
60
|
+
"name": "Improvement",
|
61
|
+
"subtask": false
|
62
|
+
},
|
63
|
+
{
|
64
|
+
"self": "http://localhost:2990/jira/rest/api/2/issuetype/5",
|
65
|
+
"id": "5",
|
66
|
+
"description": "The sub-task of the issue",
|
67
|
+
"iconUrl": "http://localhost:2990/jira/images/icons/issue_subtask.gif",
|
68
|
+
"name": "Sub-task",
|
69
|
+
"subtask": true
|
70
|
+
}
|
71
|
+
],
|
72
|
+
"assigneeType": "PROJECT_LEAD",
|
73
|
+
"versions": [],
|
74
|
+
"name": "Sample Project for Developing RoR RESTful API",
|
75
|
+
"roles": {
|
76
|
+
"Users": "http://localhost:2990/jira/rest/api/2/project/SAMPLEPROJECT/role/10000",
|
77
|
+
"Administrators": "http://localhost:2990/jira/rest/api/2/project/SAMPLEPROJECT/role/10002",
|
78
|
+
"Developers": "http://localhost:2990/jira/rest/api/2/project/SAMPLEPROJECT/role/10001"
|
79
|
+
},
|
80
|
+
"avatarUrls": {
|
81
|
+
"16x16": "http://localhost:2990/jira/secure/projectavatar?size=small&pid=10001&avatarId=10011",
|
82
|
+
"48x48": "http://localhost:2990/jira/secure/projectavatar?pid=10001&avatarId=10011"
|
83
|
+
}
|
84
|
+
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
[
|
2
|
+
{
|
3
|
+
"self": "http://localhost:2990/jira/rest/api/2/project/SAMPLEPROJECT",
|
4
|
+
"id": "10001",
|
5
|
+
"key": "SAMPLEPROJECT",
|
6
|
+
"name": "Sample Project for Developing RoR RESTful API",
|
7
|
+
"avatarUrls": {
|
8
|
+
"16x16": "http://localhost:2990/jira/secure/projectavatar?size=small&pid=10001&avatarId=10011",
|
9
|
+
"48x48": "http://localhost:2990/jira/secure/projectavatar?pid=10001&avatarId=10011"
|
10
|
+
}
|
11
|
+
}
|
12
|
+
]
|
@@ -0,0 +1,37 @@
|
|
1
|
+
[
|
2
|
+
{
|
3
|
+
"self": "http://localhost:2990/jira/rest/api/2/status/1",
|
4
|
+
"description": "The issue is open and ready for the assignee to start work on it.",
|
5
|
+
"iconUrl": "http://localhost:2990/jira/images/icons/status_open.gif",
|
6
|
+
"name": "Open",
|
7
|
+
"id": "1"
|
8
|
+
},
|
9
|
+
{
|
10
|
+
"self": "http://localhost:2990/jira/rest/api/2/status/3",
|
11
|
+
"description": "This issue is being actively worked on at the moment by the assignee.",
|
12
|
+
"iconUrl": "http://localhost:2990/jira/images/icons/status_inprogress.gif",
|
13
|
+
"name": "In Progress",
|
14
|
+
"id": "3"
|
15
|
+
},
|
16
|
+
{
|
17
|
+
"self": "http://localhost:2990/jira/rest/api/2/status/4",
|
18
|
+
"description": "This issue was once resolved, but the resolution was deemed incorrect. From here issues are either marked assigned or resolved.",
|
19
|
+
"iconUrl": "http://localhost:2990/jira/images/icons/status_reopened.gif",
|
20
|
+
"name": "Reopened",
|
21
|
+
"id": "4"
|
22
|
+
},
|
23
|
+
{
|
24
|
+
"self": "http://localhost:2990/jira/rest/api/2/status/5",
|
25
|
+
"description": "A resolution has been taken, and it is awaiting verification by reporter. From here issues are either reopened, or are closed.",
|
26
|
+
"iconUrl": "http://localhost:2990/jira/images/icons/status_resolved.gif",
|
27
|
+
"name": "Resolved",
|
28
|
+
"id": "5"
|
29
|
+
},
|
30
|
+
{
|
31
|
+
"self": "http://localhost:2990/jira/rest/api/2/status/6",
|
32
|
+
"description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.",
|
33
|
+
"iconUrl": "http://localhost:2990/jira/images/icons/status_closed.gif",
|
34
|
+
"name": "Closed",
|
35
|
+
"id": "6"
|
36
|
+
}
|
37
|
+
]
|
@@ -0,0 +1,17 @@
|
|
1
|
+
{
|
2
|
+
"self": "http://localhost:2990/jira/rest/api/2/user?username=admin",
|
3
|
+
"name": "admin",
|
4
|
+
"emailAddress": "admin@example.com",
|
5
|
+
"avatarUrls": {
|
6
|
+
"16x16": "http://localhost:2990/jira/secure/useravatar?size=small&avatarId=10122",
|
7
|
+
"48x48": "http://localhost:2990/jira/secure/useravatar?avatarId=10122"
|
8
|
+
},
|
9
|
+
"displayName": "admin",
|
10
|
+
"active": true,
|
11
|
+
"timeZone": "Pacific/Auckland",
|
12
|
+
"groups": {
|
13
|
+
"size": 3,
|
14
|
+
"items": []
|
15
|
+
},
|
16
|
+
"expand": "groups"
|
17
|
+
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
{
|
2
|
+
"self": "http://localhost:2990/jira/rest/api/2/version/10000",
|
3
|
+
"id": "10000",
|
4
|
+
"description": "Initial version",
|
5
|
+
"name": "1.0",
|
6
|
+
"overdue": false,
|
7
|
+
"userReleaseDate": "12/Jan/12",
|
8
|
+
"archived": false,
|
9
|
+
"releaseDate": "2012-01-12",
|
10
|
+
"released": false
|
11
|
+
}
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'webmock/rspec'
|
5
|
+
Dir["./spec/support/**/*.rb"].each {|f| require f}
|
6
|
+
|
7
|
+
require 'jira'
|
8
|
+
|
9
|
+
RSpec.configure do |config|
|
10
|
+
config.extend ClientsHelper
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
def get_mock_response(file, value_if_file_not_found = false)
|
15
|
+
begin
|
16
|
+
file.sub!('?', '_') # we have to replace this character on Windows machine
|
17
|
+
File.read(File.join(File.dirname(__FILE__), 'mock_responses/', file))
|
18
|
+
rescue Errno::ENOENT => e
|
19
|
+
raise e if value_if_file_not_found == false
|
20
|
+
value_if_file_not_found
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module ClientsHelper
|
2
|
+
def with_each_client
|
3
|
+
clients = {}
|
4
|
+
|
5
|
+
oauth_client = JIRA::Client.new({ :consumer_key => 'foo', :consumer_secret => 'bar' })
|
6
|
+
oauth_client.set_access_token('abc', '123')
|
7
|
+
clients["http://localhost:2990"] = oauth_client
|
8
|
+
|
9
|
+
basic_client = JIRA::Client.new({ :username => 'foo', :password => 'bar', :auth_type => :basic, :use_ssl => false })
|
10
|
+
clients["http://foo:bar@localhost:2990"] = basic_client
|
11
|
+
|
12
|
+
clients.each do |site_url, client|
|
13
|
+
yield site_url, client
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
RSpec::Matchers.define :have_attributes do |expected|
|
2
|
+
match do |actual|
|
3
|
+
expected.each do |key, value|
|
4
|
+
actual.attrs[key].should == value
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
failure_message_for_should do |actual|
|
9
|
+
"expected #{actual.attrs} to match #{expected}"
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
RSpec::Matchers.define :have_many do |collection, klass|
|
2
|
+
match do |actual|
|
3
|
+
actual.send(collection).class.should == JIRA::HasManyProxy
|
4
|
+
actual.send(collection).length.should > 0
|
5
|
+
actual.send(collection).each do |member|
|
6
|
+
member.class.should == klass
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,190 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
|
3
|
+
def get_mock_from_path(method, options = {})
|
4
|
+
if defined? belongs_to
|
5
|
+
prefix = belongs_to.path_component + '/'
|
6
|
+
else
|
7
|
+
prefix = ''
|
8
|
+
end
|
9
|
+
|
10
|
+
if options[:url]
|
11
|
+
url = options[:url]
|
12
|
+
elsif options[:key]
|
13
|
+
url = described_class.singular_path(client, options[:key], prefix)
|
14
|
+
else
|
15
|
+
url = described_class.collection_path(client, prefix)
|
16
|
+
end
|
17
|
+
file_path = url.sub(client.options[:rest_base_path], '')
|
18
|
+
file_path = file_path + '.' + options[:suffix] if options[:suffix]
|
19
|
+
file_path = file_path + '.' + method.to_s unless method == :get
|
20
|
+
value_if_not_found = options.keys.include?(:value_if_not_found) ? options[:value_if_not_found] : false
|
21
|
+
get_mock_response("#{file_path}.json", value_if_not_found)
|
22
|
+
end
|
23
|
+
|
24
|
+
def class_basename
|
25
|
+
described_class.name.split('::').last
|
26
|
+
end
|
27
|
+
|
28
|
+
def options
|
29
|
+
options = {}
|
30
|
+
if defined? belongs_to
|
31
|
+
options[belongs_to.to_sym] = belongs_to
|
32
|
+
end
|
33
|
+
options
|
34
|
+
end
|
35
|
+
|
36
|
+
def prefix
|
37
|
+
prefix = '/'
|
38
|
+
if defined? belongs_to
|
39
|
+
prefix = belongs_to.path_component + '/'
|
40
|
+
end
|
41
|
+
prefix
|
42
|
+
end
|
43
|
+
|
44
|
+
def build_receiver
|
45
|
+
if defined?(belongs_to)
|
46
|
+
belongs_to.send(described_class.endpoint_name.pluralize.to_sym)
|
47
|
+
else
|
48
|
+
client.send(class_basename)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
shared_examples "a resource" do
|
53
|
+
|
54
|
+
it "gracefully handles non-json responses" do
|
55
|
+
if defined? target
|
56
|
+
subject = target
|
57
|
+
else
|
58
|
+
subject = client.send(class_basename).build(described_class.key_attribute.to_s => '99999')
|
59
|
+
end
|
60
|
+
stub_request(:put, site_url + subject.url).
|
61
|
+
to_return(:status => 405, :body => "<html><body>Some HTML</body></html>")
|
62
|
+
subject.save('foo' => 'bar').should be_false
|
63
|
+
lambda do
|
64
|
+
subject.save!('foo' => 'bar').should be_false
|
65
|
+
end.should raise_error(JIRA::HTTPError)
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
shared_examples "a resource with a collection GET endpoint" do
|
71
|
+
|
72
|
+
it "should get the collection" do
|
73
|
+
stub_request(:get, site_url + described_class.collection_path(client)).
|
74
|
+
to_return(:status => 200, :body => get_mock_from_path(:get))
|
75
|
+
collection = build_receiver.all
|
76
|
+
collection.length.should == expected_collection_length
|
77
|
+
|
78
|
+
first = collection.first
|
79
|
+
first.should have_attributes(expected_attributes)
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
shared_examples "a resource with JQL inputs and a collection GET endpoint" do
|
85
|
+
|
86
|
+
it "should get the collection" do
|
87
|
+
stub_request(:get, site_url + client.options[:rest_base_path] + '/search?jql=' + CGI.escape(jql_query_string)).
|
88
|
+
to_return(:status => 200, :body => get_mock_response('issue.json'))
|
89
|
+
collection = build_receiver.jql(jql_query_string)
|
90
|
+
collection.length.should == expected_collection_length
|
91
|
+
|
92
|
+
first = collection.first
|
93
|
+
first.should have_attributes(expected_attributes)
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
shared_examples "a resource with a singular GET endpoint" do
|
99
|
+
|
100
|
+
it "GETs a single resource" do
|
101
|
+
# E.g., for JIRA::Resource::Project, we need to call
|
102
|
+
# client.Project.find()
|
103
|
+
stub_request(:get, site_url + described_class.singular_path(client, key, prefix)).
|
104
|
+
to_return(:status => 200, :body => get_mock_from_path(:get, :key => key))
|
105
|
+
subject = client.send(class_basename).find(key, options)
|
106
|
+
|
107
|
+
subject.should have_attributes(expected_attributes)
|
108
|
+
end
|
109
|
+
|
110
|
+
it "builds and fetches a single resource" do
|
111
|
+
# E.g., for JIRA::Resource::Project, we need to call
|
112
|
+
# client.Project.build('key' => 'ABC123')
|
113
|
+
stub_request(:get, site_url + described_class.singular_path(client, key, prefix)).
|
114
|
+
to_return(:status => 200, :body => get_mock_from_path(:get, :key => key))
|
115
|
+
|
116
|
+
subject = build_receiver.build(described_class.key_attribute.to_s => key)
|
117
|
+
subject.fetch
|
118
|
+
|
119
|
+
subject.should have_attributes(expected_attributes)
|
120
|
+
end
|
121
|
+
|
122
|
+
it "handles a 404" do
|
123
|
+
stub_request(:get, site_url + described_class.singular_path(client, '99999', prefix)).
|
124
|
+
to_return(:status => 404, :body => '{"errorMessages":["'+class_basename+' Does Not Exist"],"errors": {}}')
|
125
|
+
lambda do
|
126
|
+
client.send(class_basename).find('99999', options)
|
127
|
+
end.should raise_exception(JIRA::HTTPError)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
shared_examples "a resource with a DELETE endpoint" do
|
132
|
+
it "deletes a resource" do
|
133
|
+
# E.g., for JIRA::Resource::Project, we need to call
|
134
|
+
# client.Project.delete()
|
135
|
+
stub_request(:delete, site_url + described_class.singular_path(client, key, prefix)).
|
136
|
+
to_return(:status => 204, :body => nil)
|
137
|
+
|
138
|
+
subject = build_receiver.build(described_class.key_attribute.to_s => key)
|
139
|
+
subject.delete.should be_true
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
shared_examples "a resource with a POST endpoint" do
|
144
|
+
|
145
|
+
it "saves a new resource" do
|
146
|
+
stub_request(:post, site_url + described_class.collection_path(client, prefix)).
|
147
|
+
to_return(:status => 201, :body => get_mock_from_path(:post))
|
148
|
+
subject = build_receiver.build
|
149
|
+
subject.save(attributes_for_post).should be_true
|
150
|
+
expected_attributes_from_post.each do |method_name, value|
|
151
|
+
subject.send(method_name).should == value
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
|
157
|
+
shared_examples "a resource with a PUT endpoint" do
|
158
|
+
|
159
|
+
it "saves an existing component" do
|
160
|
+
stub_request(:get, site_url + described_class.singular_path(client, key, prefix)).
|
161
|
+
to_return(:status => 200, :body => get_mock_from_path(:get, :key =>key))
|
162
|
+
stub_request(:put, site_url + described_class.singular_path(client, key, prefix)).
|
163
|
+
to_return(:status => 200, :body => get_mock_from_path(:put, :key => key, :value_if_not_found => nil))
|
164
|
+
subject = build_receiver.build(described_class.key_attribute.to_s => key)
|
165
|
+
subject.fetch
|
166
|
+
subject.save(attributes_for_put).should be_true
|
167
|
+
expected_attributes_from_put.each do |method_name, value|
|
168
|
+
subject.send(method_name).should == value
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
end
|
173
|
+
|
174
|
+
shared_examples 'a resource with a PUT endpoint that rejects invalid fields' do
|
175
|
+
|
176
|
+
it "fails to save with an invalid field" do
|
177
|
+
stub_request(:get, site_url + described_class.singular_path(client, key)).
|
178
|
+
to_return(:status => 200, :body => get_mock_from_path(:get, :key => key))
|
179
|
+
stub_request(:put, site_url + described_class.singular_path(client, key)).
|
180
|
+
to_return(:status => 400, :body => get_mock_from_path(:put, :key => key, :suffix => "invalid"))
|
181
|
+
subject = client.send(class_basename).build(described_class.key_attribute.to_s => key)
|
182
|
+
subject.fetch
|
183
|
+
|
184
|
+
subject.save('fields'=> {'invalid' => 'field'}).should be_false
|
185
|
+
lambda do
|
186
|
+
subject.save!('fields'=> {'invalid' => 'field'})
|
187
|
+
end.should raise_error(JIRA::HTTPError)
|
188
|
+
end
|
189
|
+
|
190
|
+
end
|