jiraby 0.0.1
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/.gitignore +9 -0
- data/.rspec +3 -0
- data/.travis.yml +4 -0
- data/.yardopts +8 -0
- data/Gemfile +7 -0
- data/README.md +132 -0
- data/Rakefile +5 -0
- data/docs/development.md +20 -0
- data/docs/history.md +5 -0
- data/docs/ideas.md +54 -0
- data/docs/index.md +11 -0
- data/docs/usage.md +64 -0
- data/jiraby.gemspec +31 -0
- data/lib/jiraby.rb +8 -0
- data/lib/jiraby/entity.rb +21 -0
- data/lib/jiraby/exceptions.rb +8 -0
- data/lib/jiraby/issue.rb +109 -0
- data/lib/jiraby/jira.rb +319 -0
- data/lib/jiraby/json_resource.rb +136 -0
- data/lib/jiraby/project.rb +19 -0
- data/spec/data/field.json +32 -0
- data/spec/data/issue_10002.json +187 -0
- data/spec/data/issue_createmeta.json +35 -0
- data/spec/data/jira_issues.rb +265 -0
- data/spec/data/jira_projects.rb +117 -0
- data/spec/data/project_TST.json +97 -0
- data/spec/data/search_results.json +26 -0
- data/spec/entity_spec.rb +20 -0
- data/spec/issue_spec.rb +289 -0
- data/spec/jira_spec.rb +314 -0
- data/spec/json_resource_spec.rb +222 -0
- data/spec/mockapp/config.ru +6 -0
- data/spec/mockapp/index.html +10 -0
- data/spec/mockapp/jira.rb +61 -0
- data/spec/mockapp/views/auth/login_failed.erb +1 -0
- data/spec/mockapp/views/auth/login_success.erb +7 -0
- data/spec/mockapp/views/error.erb +3 -0
- data/spec/mockapp/views/field.erb +32 -0
- data/spec/mockapp/views/issue/TST-1.erb +186 -0
- data/spec/mockapp/views/issue/createmeta.erb +35 -0
- data/spec/mockapp/views/issue/err_nonexistent.erb +1 -0
- data/spec/mockapp/views/project/TST.erb +97 -0
- data/spec/mockapp/views/project/err_nonexistent.erb +4 -0
- data/spec/mockapp/views/search.erb +26 -0
- data/spec/project_spec.rb +20 -0
- data/spec/spec_helper.rb +26 -0
- data/tasks/mockjira.rake +10 -0
- data/tasks/pry.rake +28 -0
- data/tasks/spec.rake +9 -0
- data/tasks/test.rake +8 -0
- metadata +288 -0
@@ -0,0 +1,117 @@
|
|
1
|
+
JIRA_2_PROJECT = {
|
2
|
+
"key" => "TST",
|
3
|
+
"name" => "Test",
|
4
|
+
"id" => "10000",
|
5
|
+
"self" => "http://localhost:8080/rest/api/2/project/TST",
|
6
|
+
"assigneeType" => "PROJECT_LEAD",
|
7
|
+
"components" => [],
|
8
|
+
"versions" => [],
|
9
|
+
"issueTypes" => [
|
10
|
+
{
|
11
|
+
"name" => "Bug",
|
12
|
+
"iconUrl" => "http://localhost:8080/images/icons/bug.gif",
|
13
|
+
"self" => "http://localhost:8080/rest/api/2/issuetype/1",
|
14
|
+
"id" => "1",
|
15
|
+
"subtask" => false,
|
16
|
+
"description" => "A problem which impairs or prevents the functions of the product.",
|
17
|
+
},
|
18
|
+
{
|
19
|
+
"name" => "New Feature",
|
20
|
+
"iconUrl" => "http://localhost:8080/images/icons/newfeature.gif",
|
21
|
+
"self" => "http://localhost:8080/rest/api/2/issuetype/2",
|
22
|
+
"id" => "2",
|
23
|
+
"subtask" => false,
|
24
|
+
"description" => "A new feature of the product, which has yet to be developed.",
|
25
|
+
},
|
26
|
+
{
|
27
|
+
"name" => "Task",
|
28
|
+
"iconUrl" => "http://localhost:8080/images/icons/task.gif",
|
29
|
+
"self" => "http://localhost:8080/rest/api/2/issuetype/3",
|
30
|
+
"id" => "3",
|
31
|
+
"subtask" => false,
|
32
|
+
"description" => "A task that needs to be done.",
|
33
|
+
},
|
34
|
+
{
|
35
|
+
"name" => "Improvement",
|
36
|
+
"iconUrl" => "http://localhost:8080/images/icons/improvement.gif",
|
37
|
+
"self" => "http://localhost:8080/rest/api/2/issuetype/4",
|
38
|
+
"id" => "4",
|
39
|
+
"subtask" => false,
|
40
|
+
"description" => "An improvement or enhancement to an existing feature or task.",
|
41
|
+
},
|
42
|
+
{
|
43
|
+
"name" => "Sub-task",
|
44
|
+
"iconUrl" => "http://localhost:8080/images/icons/issue_subtask.gif",
|
45
|
+
"self" => "http://localhost:8080/rest/api/2/issuetype/5",
|
46
|
+
"id" => "5",
|
47
|
+
"subtask" => true,
|
48
|
+
"description" => "The sub-task of the issue",
|
49
|
+
},
|
50
|
+
],
|
51
|
+
"avatarUrls" => {
|
52
|
+
"48x48" => "http://localhost:8080/secure/projectavatar?pid=10000&avatarId=10011",
|
53
|
+
"16x16" => "http://localhost:8080/secure/projectavatar?size=small&pid=10000&avatarId=10011",
|
54
|
+
},
|
55
|
+
"roles" => {
|
56
|
+
"Developers" => "http://localhost:8080/rest/api/2/project/TST/role/10001",
|
57
|
+
"Administrators" => "http://localhost:8080/rest/api/2/project/TST/role/10002",
|
58
|
+
"Users" => "http://localhost:8080/rest/api/2/project/TST/role/10000",
|
59
|
+
},
|
60
|
+
"lead" => {
|
61
|
+
"name" => "admin",
|
62
|
+
"self" => "http://localhost:8080/rest/api/2/user?username=admin",
|
63
|
+
"displayName" => "Administrator",
|
64
|
+
"active" => true,
|
65
|
+
"avatarUrls" => {
|
66
|
+
"48x48" => "http://localhost:8080/secure/useravatar?avatarId=10122",
|
67
|
+
"16x16" => "http://localhost:8080/secure/useravatar?size=small&avatarId=10122",
|
68
|
+
},
|
69
|
+
},
|
70
|
+
}
|
71
|
+
|
72
|
+
JIRA_2_ALPHA_PROJECT = {
|
73
|
+
"key" => "TST",
|
74
|
+
"name" => "Test",
|
75
|
+
"self" => "http://localhost:8080/rest/api/2.0.alpha1/project/TST",
|
76
|
+
"assigneeType" => "PROJECT_LEAD",
|
77
|
+
"components" => [],
|
78
|
+
"versions" => [],
|
79
|
+
"issueTypes" => [
|
80
|
+
{
|
81
|
+
"name" => "Bug",
|
82
|
+
"self" => "http://localhost:8080/rest/api/2.0.alpha1/issueType/1",
|
83
|
+
"subtask" => false,
|
84
|
+
},
|
85
|
+
{
|
86
|
+
"name" => "New Feature",
|
87
|
+
"self" => "http://localhost:8080/rest/api/2.0.alpha1/issueType/2",
|
88
|
+
"subtask" => false,
|
89
|
+
},
|
90
|
+
{
|
91
|
+
"name" => "Task",
|
92
|
+
"self" => "http://localhost:8080/rest/api/2.0.alpha1/issueType/3",
|
93
|
+
"subtask" => false,
|
94
|
+
},
|
95
|
+
{
|
96
|
+
"name" => "Improvement",
|
97
|
+
"self" => "http://localhost:8080/rest/api/2.0.alpha1/issueType/4",
|
98
|
+
"subtask" => false,
|
99
|
+
},
|
100
|
+
{
|
101
|
+
"name" => "Sub-task",
|
102
|
+
"self" => "http://localhost:8080/rest/api/2.0.alpha1/issueType/5",
|
103
|
+
"subtask" => true,
|
104
|
+
},
|
105
|
+
],
|
106
|
+
"roles" => {
|
107
|
+
"Developers" => "http://localhost:8080/rest/api/2.0.alpha1/project/TST/role/10001",
|
108
|
+
"Administrators" => "http://localhost:8080/rest/api/2.0.alpha1/project/TST/role/10002",
|
109
|
+
"Users" => "http://localhost:8080/rest/api/2.0.alpha1/project/TST/role/10000",
|
110
|
+
},
|
111
|
+
"lead" => {
|
112
|
+
"name" => "admin",
|
113
|
+
"self" => "http://localhost:8080/rest/api/2.0.alpha1/user?username=admin",
|
114
|
+
"displayName" => "Administrator",
|
115
|
+
"active" => true,
|
116
|
+
},
|
117
|
+
}
|
@@ -0,0 +1,97 @@
|
|
1
|
+
{
|
2
|
+
"self": "http://www.example.com/jira/rest/api/2/project/TST",
|
3
|
+
"id": "10000",
|
4
|
+
"key": "TST",
|
5
|
+
"description": "This project was created as an example for REST.",
|
6
|
+
"lead": {
|
7
|
+
"self": "http://www.example.com/jira/rest/api/2/user?username=fred",
|
8
|
+
"name": "fred",
|
9
|
+
"avatarUrls": {
|
10
|
+
"24x24": "http://www.example.com/jira/secure/useravatar?size=small&ownerId=fred",
|
11
|
+
"16x16": "http://www.example.com/jira/secure/useravatar?size=xsmall&ownerId=fred",
|
12
|
+
"32x32": "http://www.example.com/jira/secure/useravatar?size=medium&ownerId=fred",
|
13
|
+
"48x48": "http://www.example.com/jira/secure/useravatar?size=large&ownerId=fred"
|
14
|
+
},
|
15
|
+
"displayName": "Fred F. User",
|
16
|
+
"active": false
|
17
|
+
},
|
18
|
+
"components": [
|
19
|
+
{
|
20
|
+
"self": "http://www.example.com/jira/rest/api/2/component/10000",
|
21
|
+
"id": "10000",
|
22
|
+
"name": "Component 1",
|
23
|
+
"description": "This is a JIRA component",
|
24
|
+
"lead": {
|
25
|
+
"self": "http://www.example.com/jira/rest/api/2/user?username=fred",
|
26
|
+
"name": "fred",
|
27
|
+
"avatarUrls": {
|
28
|
+
"24x24": "http://www.example.com/jira/secure/useravatar?size=small&ownerId=fred",
|
29
|
+
"16x16": "http://www.example.com/jira/secure/useravatar?size=xsmall&ownerId=fred",
|
30
|
+
"32x32": "http://www.example.com/jira/secure/useravatar?size=medium&ownerId=fred",
|
31
|
+
"48x48": "http://www.example.com/jira/secure/useravatar?size=large&ownerId=fred"
|
32
|
+
},
|
33
|
+
"displayName": "Fred F. User",
|
34
|
+
"active": false
|
35
|
+
},
|
36
|
+
"assigneeType": "PROJECT_LEAD",
|
37
|
+
"assignee": {
|
38
|
+
"self": "http://www.example.com/jira/rest/api/2/user?username=fred",
|
39
|
+
"name": "fred",
|
40
|
+
"avatarUrls": {
|
41
|
+
"24x24": "http://www.example.com/jira/secure/useravatar?size=small&ownerId=fred",
|
42
|
+
"16x16": "http://www.example.com/jira/secure/useravatar?size=xsmall&ownerId=fred",
|
43
|
+
"32x32": "http://www.example.com/jira/secure/useravatar?size=medium&ownerId=fred",
|
44
|
+
"48x48": "http://www.example.com/jira/secure/useravatar?size=large&ownerId=fred"
|
45
|
+
},
|
46
|
+
"displayName": "Fred F. User",
|
47
|
+
"active": false
|
48
|
+
},
|
49
|
+
"realAssigneeType": "PROJECT_LEAD",
|
50
|
+
"realAssignee": {
|
51
|
+
"self": "http://www.example.com/jira/rest/api/2/user?username=fred",
|
52
|
+
"name": "fred",
|
53
|
+
"avatarUrls": {
|
54
|
+
"24x24": "http://www.example.com/jira/secure/useravatar?size=small&ownerId=fred",
|
55
|
+
"16x16": "http://www.example.com/jira/secure/useravatar?size=xsmall&ownerId=fred",
|
56
|
+
"32x32": "http://www.example.com/jira/secure/useravatar?size=medium&ownerId=fred",
|
57
|
+
"48x48": "http://www.example.com/jira/secure/useravatar?size=large&ownerId=fred"
|
58
|
+
},
|
59
|
+
"displayName": "Fred F. User",
|
60
|
+
"active": false
|
61
|
+
},
|
62
|
+
"isAssigneeTypeValid": false
|
63
|
+
}
|
64
|
+
],
|
65
|
+
"issueTypes": [
|
66
|
+
{
|
67
|
+
"self": "http://localhost:8090/jira/rest/api/2.0/issueType/3",
|
68
|
+
"id": "3",
|
69
|
+
"description": "A task that needs to be done.",
|
70
|
+
"iconUrl": "http://localhost:8090/jira/images/icons/issuetypes/task.png",
|
71
|
+
"name": "Task",
|
72
|
+
"subtask": false
|
73
|
+
},
|
74
|
+
{
|
75
|
+
"self": "http://localhost:8090/jira/rest/api/2.0/issueType/1",
|
76
|
+
"id": "1",
|
77
|
+
"description": "A problem with the software.",
|
78
|
+
"iconUrl": "http://localhost:8090/jira/images/icons/issuetypes/bug.png",
|
79
|
+
"name": "Bug",
|
80
|
+
"subtask": false
|
81
|
+
}
|
82
|
+
],
|
83
|
+
"url": "http://www.example.com/jira/browse/TST",
|
84
|
+
"email": "from-jira@example.com",
|
85
|
+
"assigneeType": "PROJECT_LEAD",
|
86
|
+
"versions": [],
|
87
|
+
"name": "Example",
|
88
|
+
"roles": {
|
89
|
+
"Developers": "http://www.example.com/jira/rest/api/2/project/TST/role/10000"
|
90
|
+
},
|
91
|
+
"avatarUrls": {
|
92
|
+
"24x24": "http://www.example.com/jira/secure/projectavatar?size=small&pid=10000",
|
93
|
+
"16x16": "http://www.example.com/jira/secure/projectavatar?size=xsmall&pid=10000",
|
94
|
+
"32x32": "http://www.example.com/jira/secure/projectavatar?size=medium&pid=10000",
|
95
|
+
"48x48": "http://www.example.com/jira/secure/projectavatar?size=large&pid=10000"
|
96
|
+
}
|
97
|
+
}
|
@@ -0,0 +1,26 @@
|
|
1
|
+
{
|
2
|
+
"expand": "names,schema",
|
3
|
+
"startAt": 0,
|
4
|
+
"maxResults": 50,
|
5
|
+
"total": 3,
|
6
|
+
"issues": [
|
7
|
+
{
|
8
|
+
"key": "TST-1",
|
9
|
+
"id": "1001",
|
10
|
+
"self": "http://www.example.com/jira/rest/api/2/issue/1001",
|
11
|
+
"expand": ""
|
12
|
+
},
|
13
|
+
{
|
14
|
+
"key": "TST-2",
|
15
|
+
"id": "1002",
|
16
|
+
"self": "http://www.example.com/jira/rest/api/2/issue/1002",
|
17
|
+
"expand": ""
|
18
|
+
},
|
19
|
+
{
|
20
|
+
"key": "TST-3",
|
21
|
+
"id": "1003",
|
22
|
+
"self": "http://www.example.com/jira/rest/api/2/issue/1003",
|
23
|
+
"expand": ""
|
24
|
+
}
|
25
|
+
]
|
26
|
+
}
|
data/spec/entity_spec.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
describe Jiraby::Entity do
|
4
|
+
before(:each) do
|
5
|
+
@ent = Jiraby::Entity.new(json_data('issue_10002.json'))
|
6
|
+
end
|
7
|
+
|
8
|
+
describe '#key' do
|
9
|
+
it "passes through to Hash#key if arguments are included" do
|
10
|
+
@ent.key('10002').should == 'id'
|
11
|
+
@ent.key('TST-1').should == 'key'
|
12
|
+
end
|
13
|
+
|
14
|
+
it "returns the value in the issue's `key` field if argument is omitted" do
|
15
|
+
@ent.key.should == 'TST-1'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
data/spec/issue_spec.rb
ADDED
@@ -0,0 +1,289 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
require_relative 'data/jira_issues'
|
3
|
+
|
4
|
+
describe Jiraby::Issue do
|
5
|
+
before(:each) do
|
6
|
+
@field_mapping = {
|
7
|
+
'description' => 'Description',
|
8
|
+
'customfield_10001' => 'Custom Field',
|
9
|
+
}
|
10
|
+
@jira = Jiraby::Jira.new('jira.example.com', 'username', 'password')
|
11
|
+
@jira.stub(:field_mapping => @field_mapping)
|
12
|
+
@issue = Jiraby::Issue.new(@jira, json_data('issue_10002.json'))
|
13
|
+
end
|
14
|
+
|
15
|
+
context "Class methods" do
|
16
|
+
end # Class methods
|
17
|
+
|
18
|
+
context "Instance methods" do
|
19
|
+
describe '#initialize' do
|
20
|
+
it "accepts a JSON hash structure" do
|
21
|
+
json = json_data('issue_10002.json')
|
22
|
+
issue = Jiraby::Issue.new(@jira, json)
|
23
|
+
issue.data.should == json
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "#[]" do
|
28
|
+
it "accepts field `id`" do
|
29
|
+
@issue['description'].should == "example bug report"
|
30
|
+
end
|
31
|
+
|
32
|
+
it "accepts field `name`" do
|
33
|
+
@issue['Custom Field'].should == "custom field value"
|
34
|
+
end
|
35
|
+
|
36
|
+
it "returns the value set by `#[]=`" do
|
37
|
+
@issue['description'] = "Foobar"
|
38
|
+
@issue['description'].should == "Foobar"
|
39
|
+
end
|
40
|
+
|
41
|
+
it "raises an exception on invalid field name" do
|
42
|
+
lambda do
|
43
|
+
@issue['bogus']
|
44
|
+
end.should raise_error(
|
45
|
+
Jiraby::InvalidField, /Invalid field name or ID: bogus/)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "#[]=" do
|
50
|
+
it "accepts field `id`" do
|
51
|
+
@issue['description'] = "Foobar"
|
52
|
+
@issue.pending_changes['description'].should == "Foobar"
|
53
|
+
end
|
54
|
+
|
55
|
+
it "accepts field `name`" do
|
56
|
+
@issue['Custom Field'] = "Modified"
|
57
|
+
@issue.pending_changes[@field_mapping.key('Custom Field')].should == "Modified"
|
58
|
+
end
|
59
|
+
|
60
|
+
it "raises an exception on invalid field name" do
|
61
|
+
lambda do
|
62
|
+
@issue['bogus'] = "Modified"
|
63
|
+
end.should raise_error(
|
64
|
+
Jiraby::InvalidField, /Invalid field name or ID: bogus/)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "#field_id" do
|
69
|
+
before(:each) do
|
70
|
+
@ids_and_names = {
|
71
|
+
'description' => 'Description',
|
72
|
+
'sub-tasks' => 'Sub-Tasks',
|
73
|
+
'project' => 'Project',
|
74
|
+
}
|
75
|
+
@jira.stub(:field_mapping => @ids_and_names)
|
76
|
+
end
|
77
|
+
|
78
|
+
it "returns ID as-is" do
|
79
|
+
@ids_and_names.keys.each do |id|
|
80
|
+
@issue.field_id(id).should == id
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
it "returns the ID for a given name" do
|
85
|
+
@ids_and_names.each do |id, name|
|
86
|
+
@issue.field_id(name).should == id
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
it "raises an exception when invalid name or ID is given" do
|
91
|
+
lambda do
|
92
|
+
@issue.field_id("Completely Bogus")
|
93
|
+
end.should raise_error(/Invalid field name or ID/)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "#key" do
|
98
|
+
it "returns nil if the key is undefined" do
|
99
|
+
issue = Jiraby::Issue.new(@jira, {})
|
100
|
+
issue.key.should be_nil
|
101
|
+
end
|
102
|
+
|
103
|
+
it "returns the key field from the issue's data" do
|
104
|
+
@issue.key.should == @issue.data['key']
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "#editmeta" do
|
109
|
+
it "requests editmeta for the current issue" do
|
110
|
+
@jira.should_receive(:get).
|
111
|
+
with("issue/#{@issue.key}/editmeta").
|
112
|
+
and_return({})
|
113
|
+
@issue.editmeta
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe "#pending_changes?" do
|
118
|
+
it "returns true if updates are pending" do
|
119
|
+
@issue["description"] = "Foo"
|
120
|
+
@issue.pending_changes?.should be_true
|
121
|
+
end
|
122
|
+
|
123
|
+
it "returns false if no updates are pending" do
|
124
|
+
@issue.pending_changes?.should be_false
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe "#save!" do
|
129
|
+
it "sends a PUT request to Jira with updates" do
|
130
|
+
@issue['description'] = "Modified description"
|
131
|
+
expect_fields = {
|
132
|
+
'fields' => @issue.pending_changes
|
133
|
+
}
|
134
|
+
@jira.should_receive(:put).
|
135
|
+
with("issue/#{@issue.key}", expect_fields)
|
136
|
+
@issue.save!
|
137
|
+
end
|
138
|
+
|
139
|
+
it "updates the data attribute with the new changes" do
|
140
|
+
@jira.stub(:put)
|
141
|
+
original_description = @issue['description']
|
142
|
+
modified_description = "Modified description"
|
143
|
+
|
144
|
+
@issue.data.fields.description.should == original_description
|
145
|
+
@issue['description'] = modified_description
|
146
|
+
@issue.save!
|
147
|
+
@issue.data.fields.description.should == modified_description
|
148
|
+
end
|
149
|
+
|
150
|
+
it "resets pending_changes" do
|
151
|
+
@jira.stub(:put => nil)
|
152
|
+
@issue['description'] = "Modified description"
|
153
|
+
@issue.pending_changes.should_not be_empty
|
154
|
+
@issue.pending_changes?.should be_true
|
155
|
+
@issue.save!
|
156
|
+
@issue.pending_changes.should be_empty
|
157
|
+
@issue.pending_changes?.should be_false
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
describe "#has_field?" do
|
162
|
+
before(:each) do
|
163
|
+
@ids_and_names = {
|
164
|
+
'description' => 'Description',
|
165
|
+
'sub-tasks' => 'Sub-Tasks',
|
166
|
+
'project' => 'Project',
|
167
|
+
}
|
168
|
+
@jira.stub(:field_mapping => @ids_and_names)
|
169
|
+
end
|
170
|
+
|
171
|
+
it "true when issue has a field with the given ID" do
|
172
|
+
@ids_and_names.keys.each do |id|
|
173
|
+
@issue.has_field?(id).should be_true
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
it "true when issue has a field with the given name" do
|
178
|
+
@ids_and_names.values.each do |name|
|
179
|
+
@issue.has_field?(name).should be_true
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
it "false when issue has a no field with the given ID or name" do
|
184
|
+
@issue.has_field?("Completely Bogus").should be_false
|
185
|
+
end
|
186
|
+
end #has_field?
|
187
|
+
|
188
|
+
describe "#is_subtask?" do
|
189
|
+
it "true when issuetype.subtask is true" do
|
190
|
+
data = { 'fields' => { 'issuetype' => {'subtask' => true} } }
|
191
|
+
issue = Jiraby::Issue.new(@jira, data)
|
192
|
+
issue.is_subtask?.should be_true
|
193
|
+
end
|
194
|
+
|
195
|
+
it "false when issuetype.subtask is false" do
|
196
|
+
data = { 'fields' => { 'issuetype' => {'subtask' => false} } }
|
197
|
+
issue = Jiraby::Issue.new(@jira, data)
|
198
|
+
issue.is_subtask?.should be_false
|
199
|
+
end
|
200
|
+
|
201
|
+
it "false when issuetype.subtask is not set" do
|
202
|
+
data = { 'fields' => { 'issuetype' => {} } }
|
203
|
+
issue = Jiraby::Issue.new(@jira, data)
|
204
|
+
issue.is_subtask?.should be_false
|
205
|
+
end
|
206
|
+
end #is_subtask?
|
207
|
+
|
208
|
+
describe "#is_assigned?" do
|
209
|
+
it "true when assignee is set" do
|
210
|
+
data = { 'fields' => { 'assignee' => {'name' => 'someone'} } }
|
211
|
+
issue = Jiraby::Issue.new(@jira, data)
|
212
|
+
issue.is_assigned?.should be_true
|
213
|
+
end
|
214
|
+
|
215
|
+
it "false when assignee is nil" do
|
216
|
+
data = { 'fields' => { 'assignee' => nil } }
|
217
|
+
issue = Jiraby::Issue.new(@jira, data)
|
218
|
+
issue.is_assigned?.should be_false
|
219
|
+
end
|
220
|
+
end #is_assigned?
|
221
|
+
|
222
|
+
describe "#parent" do
|
223
|
+
it "returns the parent key when issue is a subtask" do
|
224
|
+
parent_key = 'FOO-234'
|
225
|
+
data = {
|
226
|
+
'fields' => {
|
227
|
+
'parent' => {'key' => parent_key},
|
228
|
+
'issuetype' => {'subtask' => true},
|
229
|
+
}
|
230
|
+
}
|
231
|
+
issue = Jiraby::Issue.new(@jira, data)
|
232
|
+
issue.parent.should == parent_key
|
233
|
+
end
|
234
|
+
|
235
|
+
it "returns nil when issue is not a subtask" do
|
236
|
+
data = {
|
237
|
+
'fields' => {
|
238
|
+
'issuetype' => {'subtask' => false},
|
239
|
+
}
|
240
|
+
}
|
241
|
+
issue = Jiraby::Issue.new(@jira, data)
|
242
|
+
issue.parent.should be_nil
|
243
|
+
end
|
244
|
+
end #parent
|
245
|
+
|
246
|
+
describe "#subtasks" do
|
247
|
+
it "returns an array of subtask keys" do
|
248
|
+
subtask_keys = ['ST-01', 'ST-02', 'ST-03']
|
249
|
+
data = {
|
250
|
+
'fields' => {
|
251
|
+
'subtasks' => [
|
252
|
+
{'key' => 'ST-01'},
|
253
|
+
{'key' => 'ST-02'},
|
254
|
+
{'key' => 'ST-03'},
|
255
|
+
]
|
256
|
+
}
|
257
|
+
}
|
258
|
+
issue = Jiraby::Issue.new(@jira, data)
|
259
|
+
issue.subtasks.should == subtask_keys
|
260
|
+
end
|
261
|
+
|
262
|
+
it "returns an empty array if the issue has no subtasks" do
|
263
|
+
data = {
|
264
|
+
'fields' => {
|
265
|
+
'subtasks' => []
|
266
|
+
}
|
267
|
+
}
|
268
|
+
issue = Jiraby::Issue.new(@jira, data)
|
269
|
+
issue.subtasks.should == []
|
270
|
+
end
|
271
|
+
end #subtasks
|
272
|
+
|
273
|
+
describe "#field_ids" do
|
274
|
+
it "returns a sorted array of the issue's field IDs" do
|
275
|
+
data = {
|
276
|
+
'fields' => {
|
277
|
+
'foo' => 'x',
|
278
|
+
'bar' => 'y',
|
279
|
+
'baz' => 'z',
|
280
|
+
}
|
281
|
+
}
|
282
|
+
issue = Jiraby::Issue.new(@jira, data)
|
283
|
+
issue.field_ids.should == ['bar', 'baz', 'foo']
|
284
|
+
end
|
285
|
+
end #field_ids
|
286
|
+
|
287
|
+
end # Instance methods"
|
288
|
+
end
|
289
|
+
|