jira-ruby 2.2.0 → 3.0.0.beta1
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 +4 -4
- data/.github/ISSUE_TEMPLATE/bug_report.md +20 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.github/dependabot.yml +6 -0
- data/.github/workflows/CI.yml +28 -0
- data/.github/workflows/codeql.yml +100 -0
- data/.github/workflows/rubocop.yml +18 -0
- data/.rubocop.yml +188 -0
- data/Gemfile +11 -3
- data/Guardfile +2 -0
- data/README.md +121 -20
- data/Rakefile +4 -5
- data/jira-ruby.gemspec +11 -17
- data/lib/jira/base.rb +37 -28
- data/lib/jira/base_factory.rb +4 -1
- data/lib/jira/client.rb +65 -46
- data/lib/jira/has_many_proxy.rb +4 -2
- data/lib/jira/http_client.rb +18 -13
- data/lib/jira/http_error.rb +4 -0
- data/lib/jira/jwt_client.rb +18 -42
- data/lib/jira/oauth_client.rb +6 -3
- data/lib/jira/railtie.rb +2 -0
- data/lib/jira/request_client.rb +5 -1
- data/lib/jira/resource/agile.rb +7 -9
- data/lib/jira/resource/applinks.rb +5 -3
- data/lib/jira/resource/attachment.rb +43 -3
- data/lib/jira/resource/board.rb +5 -3
- data/lib/jira/resource/board_configuration.rb +2 -0
- data/lib/jira/resource/comment.rb +2 -0
- data/lib/jira/resource/component.rb +2 -0
- data/lib/jira/resource/createmeta.rb +3 -1
- data/lib/jira/resource/field.rb +9 -4
- data/lib/jira/resource/filter.rb +2 -0
- data/lib/jira/resource/issue.rb +35 -44
- data/lib/jira/resource/issue_picker_suggestions.rb +4 -1
- data/lib/jira/resource/issue_picker_suggestions_issue.rb +2 -0
- data/lib/jira/resource/issuelink.rb +2 -0
- data/lib/jira/resource/issuelinktype.rb +2 -0
- data/lib/jira/resource/issuetype.rb +2 -0
- data/lib/jira/resource/priority.rb +2 -0
- data/lib/jira/resource/project.rb +4 -2
- data/lib/jira/resource/rapidview.rb +5 -3
- data/lib/jira/resource/remotelink.rb +2 -0
- data/lib/jira/resource/resolution.rb +2 -0
- data/lib/jira/resource/serverinfo.rb +2 -0
- data/lib/jira/resource/sprint.rb +14 -23
- data/lib/jira/resource/status.rb +7 -1
- data/lib/jira/resource/status_category.rb +10 -0
- data/lib/jira/resource/suggested_issue.rb +2 -0
- data/lib/jira/resource/transition.rb +2 -0
- data/lib/jira/resource/user.rb +3 -1
- data/lib/jira/resource/version.rb +2 -0
- data/lib/jira/resource/watcher.rb +2 -1
- data/lib/jira/resource/webhook.rb +4 -2
- data/lib/jira/resource/worklog.rb +3 -2
- data/lib/jira/version.rb +3 -1
- data/lib/jira-ruby.rb +5 -3
- data/lib/tasks/generate.rake +4 -2
- data/spec/data/files/short.txt +1 -0
- data/spec/integration/attachment_spec.rb +3 -3
- data/spec/integration/comment_spec.rb +8 -8
- data/spec/integration/component_spec.rb +7 -7
- data/spec/integration/field_spec.rb +3 -3
- data/spec/integration/issue_spec.rb +20 -16
- data/spec/integration/issuelinktype_spec.rb +3 -3
- data/spec/integration/issuetype_spec.rb +3 -3
- data/spec/integration/priority_spec.rb +3 -3
- data/spec/integration/project_spec.rb +7 -7
- data/spec/integration/rapidview_spec.rb +9 -9
- data/spec/integration/resolution_spec.rb +3 -3
- data/spec/integration/status_category_spec.rb +20 -0
- data/spec/integration/status_spec.rb +4 -8
- data/spec/integration/transition_spec.rb +2 -2
- data/spec/integration/user_spec.rb +22 -8
- data/spec/integration/version_spec.rb +7 -7
- data/spec/integration/watcher_spec.rb +17 -18
- data/spec/integration/webhook.rb +5 -4
- data/spec/integration/worklog_spec.rb +8 -8
- data/spec/jira/base_factory_spec.rb +2 -1
- data/spec/jira/base_spec.rb +55 -41
- data/spec/jira/client_spec.rb +48 -34
- data/spec/jira/has_many_proxy_spec.rb +3 -3
- data/spec/jira/http_client_spec.rb +98 -26
- data/spec/jira/http_error_spec.rb +2 -2
- data/spec/jira/oauth_client_spec.rb +30 -8
- data/spec/jira/request_client_spec.rb +4 -4
- data/spec/jira/resource/agile_spec.rb +28 -28
- data/spec/jira/resource/attachment_spec.rb +142 -52
- data/spec/jira/resource/board_spec.rb +21 -20
- data/spec/jira/resource/createmeta_spec.rb +48 -48
- data/spec/jira/resource/field_spec.rb +30 -12
- data/spec/jira/resource/filter_spec.rb +4 -4
- data/spec/jira/resource/issue_picker_suggestions_spec.rb +18 -18
- data/spec/jira/resource/issue_spec.rb +44 -38
- data/spec/jira/resource/jira_picker_suggestions_issue_spec.rb +3 -3
- data/spec/jira/resource/project_factory_spec.rb +3 -2
- data/spec/jira/resource/project_spec.rb +16 -16
- data/spec/jira/resource/sprint_spec.rb +70 -3
- data/spec/jira/resource/status_spec.rb +21 -0
- data/spec/jira/resource/user_factory_spec.rb +4 -4
- data/spec/jira/resource/worklog_spec.rb +3 -3
- data/spec/mock_responses/sprint/1.json +13 -0
- data/spec/mock_responses/status/1.json +8 -1
- data/spec/mock_responses/status.json +40 -5
- data/spec/mock_responses/statuscategory/1.json +7 -0
- data/spec/mock_responses/statuscategory.json +30 -0
- data/spec/mock_responses/{user_username=admin.json → user_accountId=1234567890abcdef01234567.json} +2 -1
- data/spec/spec_helper.rb +1 -0
- data/spec/support/clients_helper.rb +3 -5
- data/spec/support/shared_examples/integration.rb +25 -28
- metadata +25 -257
- data/.travis.yml +0 -9
- data/example.rb +0 -232
- data/http-basic-example.rb +0 -113
- data/lib/jira/resource/sprint_report.rb +0 -8
- data/lib/jira/tasks.rb +0 -0
- data/spec/jira/jwt_uri_builder_spec.rb +0 -59
@@ -10,15 +10,33 @@ describe JIRA::Resource::Field do
|
|
10
10
|
allow(client).to receive(:cache).and_return(cache)
|
11
11
|
# info about all fields on the client
|
12
12
|
allow(client.Field).to receive(:all).and_return([
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
13
|
+
described_class.new(client,
|
14
|
+
attrs: { 'id' => 'customfield_10666', 'name' => 'Priority', 'custom' => true, 'orderable' => true, 'navigable' => true,
|
15
|
+
'searchable' => true, 'clauseNames' => ['cf[10666]', 'Priority'], 'schema' => { 'type' => 'string', 'custom' => 'com.atlassian.jira.plugin.system.customfieldtypes:select', 'customId' => 10_666 } }),
|
16
|
+
described_class.new(client,
|
17
|
+
attrs: { 'id' => 'issuekey', 'name' => 'Key', 'custom' => false, 'orderable' => false,
|
18
|
+
'navigable' => true, 'searchable' => false, 'clauseNames' => %w[id issue issuekey key] }),
|
19
|
+
described_class.new(client,
|
20
|
+
attrs: { 'id' => 'priority', 'name' => 'Priority', 'custom' => false, 'orderable' => true,
|
21
|
+
'navigable' => true, 'searchable' => true, 'clauseNames' => ['priority'], 'schema' => { 'type' => 'priority', 'system' => 'priority' } }),
|
22
|
+
described_class.new(client,
|
23
|
+
attrs: { 'id' => 'summary', 'name' => 'Summary', 'custom' => false, 'orderable' => true,
|
24
|
+
'navigable' => true, 'searchable' => true, 'clauseNames' => ['summary'], 'schema' => { 'type' => 'string', 'system' => 'summary' } }),
|
25
|
+
described_class.new(client,
|
26
|
+
attrs: { 'id' => 'issuetype', 'name' => 'Issue Type', 'custom' => false, 'orderable' => true,
|
27
|
+
'navigable' => true, 'searchable' => true, 'clauseNames' => %w[issuetype type], 'schema' => { 'type' => 'issuetype', 'system' => 'issuetype' } }),
|
28
|
+
described_class.new(client,
|
29
|
+
attrs: { 'id' => 'customfield_10111', 'name' => 'SingleWord', 'custom' => true, 'orderable' => true,
|
30
|
+
'navigable' => true, 'searchable' => true, 'clauseNames' => ['cf[10111]', 'SingleWord'], 'schema' => { 'type' => 'string', 'custom' => 'com.atlassian.jira.plugin.system.customfieldtypes:select', 'customId' => 10_111 } }),
|
31
|
+
described_class.new(client,
|
32
|
+
attrs: { 'id' => 'customfield_10222', 'name' => 'Multi Word', 'custom' => true, 'orderable' => true,
|
33
|
+
'navigable' => true, 'searchable' => true, 'clauseNames' => ['cf[10222]', 'Multi Word'], 'schema' => { 'type' => 'string', 'custom' => 'com.atlassian.jira.plugin.system.customfieldtypes:select', 'customId' => 10_222 } }),
|
34
|
+
described_class.new(client,
|
35
|
+
attrs: { 'id' => 'customfield_10333', 'name' => 'Why/N@t', 'custom' => true, 'orderable' => true,
|
36
|
+
'navigable' => true, 'searchable' => true, 'clauseNames' => ['cf[10333]', 'Why/N@t'], 'schema' => { 'type' => 'string', 'custom' => 'com.atlassian.jira.plugin.system.customfieldtypes:select', 'customId' => 10_333 } }),
|
37
|
+
described_class.new(client,
|
38
|
+
attrs: { 'id' => 'customfield_10444', 'name' => 'SingleWord', 'custom' => true, 'orderable' => true,
|
39
|
+
'navigable' => true, 'searchable' => true, 'clauseNames' => ['cf[10444]', 'SingleWord'], 'schema' => { 'type' => 'string', 'custom' => 'com.atlassian.jira.plugin.system.customfieldtypes:select', 'customId' => 10_444 } })
|
22
40
|
])
|
23
41
|
client
|
24
42
|
end
|
@@ -26,14 +44,14 @@ describe JIRA::Resource::Field do
|
|
26
44
|
describe 'field_mappings' do
|
27
45
|
shared_context 'mapped or not' do
|
28
46
|
subject do
|
29
|
-
|
30
|
-
|
47
|
+
described_class.new(client, attrs: {
|
48
|
+
'priority' => 1,
|
31
49
|
'customfield_10111' => 'data_in_custom_field',
|
32
50
|
'customfield_10222' => 'multi word custom name',
|
33
51
|
'customfield_10333' => 'complex custom name',
|
34
52
|
'customfield_10444' => 'duplicated custom name',
|
35
53
|
'customfield_10666' => 'duplicate of a system name'
|
36
|
-
|
54
|
+
})
|
37
55
|
end
|
38
56
|
|
39
57
|
it 'can find a standard field by id' do
|
@@ -48,9 +48,9 @@ describe JIRA::Resource::Filter do
|
|
48
48
|
response
|
49
49
|
end
|
50
50
|
let(:filter) do
|
51
|
-
|
52
|
-
allow(
|
53
|
-
|
51
|
+
allow(client).to receive(:get).with("#{collection_path}/42").and_return(filter_response)
|
52
|
+
allow(described_class).to receive(:collection_path).and_return(collection_path)
|
53
|
+
described_class.find(client, 42)
|
54
54
|
end
|
55
55
|
let(:jql_issue) do
|
56
56
|
{
|
@@ -90,7 +90,7 @@ describe JIRA::Resource::Filter do
|
|
90
90
|
.and_return(issue_jql_response)
|
91
91
|
issues = filter.issues
|
92
92
|
expect(issues).to be_an(Array)
|
93
|
-
expect(issues.size).to
|
93
|
+
expect(issues.size).to be(1)
|
94
94
|
expected_issue = client.Issue.build(JSON.parse(jql_issue.to_json))
|
95
95
|
expect(issues.first.attrs).to eql(expected_issue.attrs)
|
96
96
|
end
|
@@ -3,15 +3,15 @@ require 'spec_helper'
|
|
3
3
|
describe JIRA::Resource::IssuePickerSuggestions do
|
4
4
|
let(:client) do
|
5
5
|
double('client', options: {
|
6
|
-
|
7
|
-
|
6
|
+
rest_base_path: '/jira/rest/api/2'
|
7
|
+
})
|
8
8
|
end
|
9
9
|
|
10
10
|
describe 'relationships' do
|
11
11
|
subject do
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
described_class.new(client, attrs: {
|
13
|
+
'sections' => [{ 'id' => 'hs' }, { 'id' => 'cs' }]
|
14
|
+
})
|
15
15
|
end
|
16
16
|
|
17
17
|
it 'has the correct relationships' do
|
@@ -30,50 +30,50 @@ describe JIRA::Resource::IssuePickerSuggestions do
|
|
30
30
|
allow(issue_picker_suggestions).to receive(:build)
|
31
31
|
end
|
32
32
|
|
33
|
-
it '
|
33
|
+
it 'autocompletes issues' do
|
34
34
|
allow(response).to receive(:body).and_return('{"sections":[{"id": "cs"}]}')
|
35
35
|
expect(client).to receive(:get).with('/jira/rest/api/2/issue/picker?query=query')
|
36
36
|
.and_return(response)
|
37
37
|
|
38
38
|
expect(client).to receive(:IssuePickerSuggestions).and_return(issue_picker_suggestions)
|
39
|
-
expect(issue_picker_suggestions).to receive(:build).with('sections' => [{ 'id' => 'cs' }])
|
39
|
+
expect(issue_picker_suggestions).to receive(:build).with({ 'sections' => [{ 'id' => 'cs' }] })
|
40
40
|
|
41
|
-
|
41
|
+
described_class.all(client, 'query')
|
42
42
|
end
|
43
43
|
|
44
|
-
it '
|
44
|
+
it 'autocompletes issues with current jql' do
|
45
45
|
expect(client).to receive(:get).with('/jira/rest/api/2/issue/picker?query=query¤tJQL=project+%3D+PR')
|
46
46
|
.and_return(response)
|
47
47
|
|
48
|
-
|
48
|
+
described_class.all(client, 'query', current_jql: 'project = PR')
|
49
49
|
end
|
50
50
|
|
51
|
-
it '
|
51
|
+
it 'autocompletes issues with current issue jey' do
|
52
52
|
expect(client).to receive(:get).with('/jira/rest/api/2/issue/picker?query=query¤tIssueKey=PR-42')
|
53
53
|
.and_return(response)
|
54
54
|
|
55
|
-
|
55
|
+
described_class.all(client, 'query', current_issue_key: 'PR-42')
|
56
56
|
end
|
57
57
|
|
58
|
-
it '
|
58
|
+
it 'autocompletes issues with current project id' do
|
59
59
|
expect(client).to receive(:get).with('/jira/rest/api/2/issue/picker?query=query¤tProjectId=PR')
|
60
60
|
.and_return(response)
|
61
61
|
|
62
|
-
|
62
|
+
described_class.all(client, 'query', current_project_id: 'PR')
|
63
63
|
end
|
64
64
|
|
65
|
-
it '
|
65
|
+
it 'autocompletes issues with show sub tasks' do
|
66
66
|
expect(client).to receive(:get).with('/jira/rest/api/2/issue/picker?query=query&showSubTasks=true')
|
67
67
|
.and_return(response)
|
68
68
|
|
69
|
-
|
69
|
+
described_class.all(client, 'query', show_sub_tasks: true)
|
70
70
|
end
|
71
71
|
|
72
|
-
it '
|
72
|
+
it 'autocompletes issues with show sub tasks parent' do
|
73
73
|
expect(client).to receive(:get).with('/jira/rest/api/2/issue/picker?query=query&showSubTaskParent=true')
|
74
74
|
.and_return(response)
|
75
75
|
|
76
|
-
|
76
|
+
described_class.all(client, 'query', show_sub_task_parent: true)
|
77
77
|
end
|
78
78
|
end
|
79
79
|
end
|
@@ -13,19 +13,21 @@ describe JIRA::Resource::Issue do
|
|
13
13
|
|
14
14
|
describe '#respond_to?' do
|
15
15
|
describe 'when decorated by SimpleDelegator' do
|
16
|
-
before
|
16
|
+
before do
|
17
17
|
response = double
|
18
18
|
allow(response).to receive(:body).and_return('{"key":"foo","id":"101"}')
|
19
|
-
allow(
|
19
|
+
allow(described_class).to receive(:collection_path).and_return('/jira/rest/api/2/issue')
|
20
20
|
allow(client).to receive(:get).with('/jira/rest/api/2/issue/101')
|
21
21
|
.and_return(response)
|
22
22
|
|
23
|
-
issue =
|
23
|
+
issue = described_class.find(client, 101)
|
24
24
|
@decorated = JIRAResourceDelegation.new(issue)
|
25
25
|
end
|
26
|
+
|
26
27
|
it 'responds to key' do
|
27
28
|
expect(@decorated.respond_to?(:key)).to eq(true)
|
28
29
|
end
|
30
|
+
|
29
31
|
it 'does not raise an error' do
|
30
32
|
expect do
|
31
33
|
@issue.respond_to?(:project)
|
@@ -34,7 +36,7 @@ describe JIRA::Resource::Issue do
|
|
34
36
|
end
|
35
37
|
end
|
36
38
|
|
37
|
-
it '
|
39
|
+
it 'finds all issues' do
|
38
40
|
response = double
|
39
41
|
empty_response = double
|
40
42
|
issue = double
|
@@ -47,28 +49,28 @@ describe JIRA::Resource::Issue do
|
|
47
49
|
.and_return(empty_response)
|
48
50
|
|
49
51
|
expect(client).to receive(:Issue).and_return(issue)
|
50
|
-
expect(issue).to receive(:build).with('id' => '1', 'summary' => 'Bugs Everywhere')
|
52
|
+
expect(issue).to receive(:build).with({ 'id' => '1', 'summary' => 'Bugs Everywhere' })
|
51
53
|
|
52
|
-
issues =
|
54
|
+
issues = described_class.all(client)
|
53
55
|
end
|
54
56
|
|
55
|
-
it '
|
57
|
+
it 'finds an issue by key or id' do
|
56
58
|
response = double
|
57
59
|
|
58
60
|
allow(response).to receive(:body).and_return('{"key":"foo","id":"101"}')
|
59
|
-
allow(
|
61
|
+
allow(described_class).to receive(:collection_path).and_return('/jira/rest/api/2/issue')
|
60
62
|
expect(client).to receive(:get).with('/jira/rest/api/2/issue/foo')
|
61
63
|
.and_return(response)
|
62
64
|
expect(client).to receive(:get).with('/jira/rest/api/2/issue/101')
|
63
65
|
.and_return(response)
|
64
66
|
|
65
|
-
issue_from_id =
|
66
|
-
issue_from_key =
|
67
|
+
issue_from_id = described_class.find(client, 101)
|
68
|
+
issue_from_key = described_class.find(client, 'foo')
|
67
69
|
|
68
70
|
expect(issue_from_id.attrs).to eq(issue_from_key.attrs)
|
69
71
|
end
|
70
72
|
|
71
|
-
it '
|
73
|
+
it 'searches an issue with a jql query string' do
|
72
74
|
response = double
|
73
75
|
issue = double
|
74
76
|
|
@@ -78,10 +80,10 @@ describe JIRA::Resource::Issue do
|
|
78
80
|
expect(client).to receive(:Issue).and_return(issue)
|
79
81
|
expect(issue).to receive(:build).with(%w[key foo]).and_return('')
|
80
82
|
|
81
|
-
expect(
|
83
|
+
expect(described_class.jql(client, 'foo bar')).to eq([''])
|
82
84
|
end
|
83
85
|
|
84
|
-
it '
|
86
|
+
it 'searches an issue with a jql query string and fields' do
|
85
87
|
response = double
|
86
88
|
issue = double
|
87
89
|
|
@@ -92,10 +94,10 @@ describe JIRA::Resource::Issue do
|
|
92
94
|
expect(client).to receive(:Issue).and_return(issue)
|
93
95
|
expect(issue).to receive(:build).with(%w[key foo]).and_return('')
|
94
96
|
|
95
|
-
expect(
|
97
|
+
expect(described_class.jql(client, 'foo bar', fields: %w[foo bar])).to eq([''])
|
96
98
|
end
|
97
99
|
|
98
|
-
it '
|
100
|
+
it 'searches an issue with a jql query string, start at, and maxResults' do
|
99
101
|
response = double
|
100
102
|
issue = double
|
101
103
|
|
@@ -106,10 +108,10 @@ describe JIRA::Resource::Issue do
|
|
106
108
|
expect(client).to receive(:Issue).and_return(issue)
|
107
109
|
expect(issue).to receive(:build).with(%w[key foo]).and_return('')
|
108
110
|
|
109
|
-
expect(
|
111
|
+
expect(described_class.jql(client, 'foo bar', start_at: 1, max_results: 3)).to eq([''])
|
110
112
|
end
|
111
113
|
|
112
|
-
it '
|
114
|
+
it 'searches an issue with a jql query string and maxResults equals zero and should return the count of tickets' do
|
113
115
|
response = double
|
114
116
|
issue = double
|
115
117
|
|
@@ -118,10 +120,10 @@ describe JIRA::Resource::Issue do
|
|
118
120
|
.with('/jira/rest/api/2/search?jql=foo+bar&maxResults=0')
|
119
121
|
.and_return(response)
|
120
122
|
|
121
|
-
expect(
|
123
|
+
expect(described_class.jql(client, 'foo bar', max_results: 0)).to eq(1)
|
122
124
|
end
|
123
125
|
|
124
|
-
it '
|
126
|
+
it 'searches an issue with a jql query string and string expand' do
|
125
127
|
response = double
|
126
128
|
issue = double
|
127
129
|
|
@@ -132,10 +134,10 @@ describe JIRA::Resource::Issue do
|
|
132
134
|
expect(client).to receive(:Issue).and_return(issue)
|
133
135
|
expect(issue).to receive(:build).with(%w[key foo]).and_return('')
|
134
136
|
|
135
|
-
expect(
|
137
|
+
expect(described_class.jql(client, 'foo bar', expand: 'transitions')).to eq([''])
|
136
138
|
end
|
137
139
|
|
138
|
-
it '
|
140
|
+
it 'searches an issue with a jql query string and array expand' do
|
139
141
|
response = double
|
140
142
|
issue = double
|
141
143
|
|
@@ -146,11 +148,11 @@ describe JIRA::Resource::Issue do
|
|
146
148
|
expect(client).to receive(:Issue).and_return(issue)
|
147
149
|
expect(issue).to receive(:build).with(%w[key foo]).and_return('')
|
148
150
|
|
149
|
-
expect(
|
151
|
+
expect(described_class.jql(client, 'foo bar', expand: %w[transitions])).to eq([''])
|
150
152
|
end
|
151
153
|
|
152
|
-
it '
|
153
|
-
subject =
|
154
|
+
it 'returns meta data available for editing an issue' do
|
155
|
+
subject = described_class.new(client, attrs: { 'fields' => { 'key' => 'TST=123' } })
|
154
156
|
response = double
|
155
157
|
|
156
158
|
allow(response).to receive(:body).and_return(
|
@@ -164,29 +166,30 @@ describe JIRA::Resource::Issue do
|
|
164
166
|
end
|
165
167
|
|
166
168
|
it 'provides direct accessors to the fields' do
|
167
|
-
subject =
|
169
|
+
subject = described_class.new(client, attrs: { 'fields' => { 'foo' => 'bar' } })
|
168
170
|
expect(subject).to respond_to(:foo)
|
169
171
|
expect(subject.foo).to eq('bar')
|
170
172
|
end
|
171
173
|
|
172
174
|
describe 'relationships' do
|
173
175
|
subject do
|
174
|
-
|
175
|
-
|
176
|
+
described_class.new(client, attrs: {
|
177
|
+
'id' => '123',
|
176
178
|
'fields' => {
|
177
179
|
'reporter' => { 'foo' => 'bar' },
|
178
|
-
'assignee'
|
179
|
-
'project'
|
180
|
-
'priority'
|
181
|
-
'issuetype'
|
182
|
-
'status'
|
183
|
-
'
|
184
|
-
'
|
185
|
-
'
|
186
|
-
'
|
187
|
-
'
|
180
|
+
'assignee' => { 'foo' => 'bar' },
|
181
|
+
'project' => { 'foo' => 'bar' },
|
182
|
+
'priority' => { 'foo' => 'bar' },
|
183
|
+
'issuetype' => { 'foo' => 'bar' },
|
184
|
+
'status' => { 'foo' => 'bar' },
|
185
|
+
'resolution' => { 'foo' => 'bar' },
|
186
|
+
'components' => [{ 'foo' => 'bar' }, { 'baz' => 'flum' }],
|
187
|
+
'versions' => [{ 'foo' => 'bar' }, { 'baz' => 'flum' }],
|
188
|
+
'comment' => { 'comments' => [{ 'foo' => 'bar' }, { 'baz' => 'flum' }] },
|
189
|
+
'attachment' => [{ 'foo' => 'bar' }, { 'baz' => 'flum' }],
|
190
|
+
'worklog' => { 'worklogs' => [{ 'foo' => 'bar' }, { 'baz' => 'flum' }] }
|
188
191
|
}
|
189
|
-
|
192
|
+
})
|
190
193
|
end
|
191
194
|
|
192
195
|
it 'has the correct relationships' do
|
@@ -208,6 +211,9 @@ describe JIRA::Resource::Issue do
|
|
208
211
|
expect(subject).to have_one(:status, JIRA::Resource::Status)
|
209
212
|
expect(subject.status.foo).to eq('bar')
|
210
213
|
|
214
|
+
expect(subject).to have_one(:resolution, JIRA::Resource::Resolution)
|
215
|
+
expect(subject.resolution.foo).to eq('bar')
|
216
|
+
|
211
217
|
expect(subject).to have_many(:components, JIRA::Resource::Component)
|
212
218
|
expect(subject.components.length).to eq(2)
|
213
219
|
|
@@ -5,9 +5,9 @@ describe JIRA::Resource::IssuePickerSuggestionsIssue do
|
|
5
5
|
|
6
6
|
describe 'relationships' do
|
7
7
|
subject do
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
described_class.new(client, attrs: {
|
9
|
+
'issues' => [{ 'id' => '1' }, { 'id' => '2' }]
|
10
|
+
})
|
11
11
|
end
|
12
12
|
|
13
13
|
it 'has the correct relationships' do
|
@@ -1,11 +1,12 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe JIRA::Resource::ProjectFactory do
|
4
|
+
subject { described_class.new(client) }
|
5
|
+
|
4
6
|
let(:client) { double }
|
5
|
-
subject { JIRA::Resource::ProjectFactory.new(client) }
|
6
7
|
|
7
8
|
it 'initializes correctly' do
|
8
|
-
expect(subject.class).to eq(
|
9
|
+
expect(subject.class).to eq(described_class)
|
9
10
|
expect(subject.client).to eq(client)
|
10
11
|
end
|
11
12
|
end
|
@@ -9,11 +9,11 @@ describe JIRA::Resource::Project do
|
|
9
9
|
|
10
10
|
describe 'relationships' do
|
11
11
|
subject do
|
12
|
-
|
13
|
-
|
14
|
-
'issueTypes'
|
15
|
-
'versions'
|
16
|
-
|
12
|
+
described_class.new(client, attrs: {
|
13
|
+
'lead' => { 'foo' => 'bar' },
|
14
|
+
'issueTypes' => [{ 'foo' => 'bar' }, { 'baz' => 'flum' }],
|
15
|
+
'versions' => [{ 'foo' => 'bar' }, { 'baz' => 'flum' }]
|
16
|
+
})
|
17
17
|
end
|
18
18
|
|
19
19
|
it 'has the correct relationships' do
|
@@ -30,13 +30,13 @@ describe JIRA::Resource::Project do
|
|
30
30
|
|
31
31
|
describe 'issues' do
|
32
32
|
subject do
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
described_class.new(client, attrs: {
|
34
|
+
'key' => 'test'
|
35
|
+
})
|
36
36
|
end
|
37
37
|
|
38
38
|
it 'returns issues' do
|
39
|
-
response_body = '{"expand":"schema,names","startAt":0,"maxResults":1,"total":1,"issues":[{"expand":"editmeta,renderedFields,transitions,changelog,operations","id":"53062","self":"/rest/api/2/issue/53062","key":"test key","fields":{"summary":"test summary"}}]}'
|
39
|
+
response_body = '{"expand":"schema,names","startAt":0,"maxResults":1,"total":1,"issues":[{"expand":"editmeta,renderedFields,transitions,changelog,operations","id":"53062","self":"/rest/api/2/issue/53062","key":"test key","fields":{"summary":"test summary"}}]}' # rubocop:disable Layout/LineLength
|
40
40
|
response = double('response',
|
41
41
|
body: response_body)
|
42
42
|
issue_factory = double('issue factory')
|
@@ -52,7 +52,7 @@ describe JIRA::Resource::Project do
|
|
52
52
|
|
53
53
|
context 'with changelog' do
|
54
54
|
it 'returns issues' do
|
55
|
-
response_body = '{"expand":"schema,names","startAt":0,"maxResults":1,"total":1,"issues":[{"expand":"editmeta,renderedFields,transitions,changelog,operations","id":"53062","self":"/rest/api/2/issue/53062","key":"test key","fields":{"summary":"test summary"},"changelog":{}}]}'
|
55
|
+
response_body = '{"expand":"schema,names","startAt":0,"maxResults":1,"total":1,"issues":[{"expand":"editmeta,renderedFields,transitions,changelog,operations","id":"53062","self":"/rest/api/2/issue/53062","key":"test key","fields":{"summary":"test summary"},"changelog":{}}]}' # rubocop:disable Layout/LineLength
|
56
56
|
response = double('response',
|
57
57
|
body: response_body)
|
58
58
|
issue_factory = double('issue factory')
|
@@ -69,12 +69,12 @@ describe JIRA::Resource::Project do
|
|
69
69
|
end
|
70
70
|
|
71
71
|
describe 'users' do
|
72
|
-
let(:project) {
|
72
|
+
let(:project) { described_class.new(client, attrs: { 'key' => project_key }) }
|
73
73
|
let(:project_key) { SecureRandom.hex }
|
74
74
|
let(:response) { double('response', body: '[{}]') }
|
75
75
|
|
76
76
|
context 'pagination' do
|
77
|
-
before
|
77
|
+
before do
|
78
78
|
user_factory = double('user factory')
|
79
79
|
expect(client).to receive(:User).and_return(user_factory)
|
80
80
|
expect(user_factory).to receive(:build).with(any_args)
|
@@ -95,7 +95,7 @@ describe JIRA::Resource::Project do
|
|
95
95
|
.with("/jira/rest/api/2/user/assignable/search?project=#{project_key}&startAt=#{start_at}")
|
96
96
|
.and_return(response)
|
97
97
|
|
98
|
-
project.users(start_at:
|
98
|
+
project.users(start_at:)
|
99
99
|
end
|
100
100
|
|
101
101
|
it 'accepts max_results option' do
|
@@ -105,7 +105,7 @@ describe JIRA::Resource::Project do
|
|
105
105
|
.with("/jira/rest/api/2/user/assignable/search?project=#{project_key}&maxResults=#{max_results}")
|
106
106
|
.and_return(response)
|
107
107
|
|
108
|
-
project.users(max_results:
|
108
|
+
project.users(max_results:)
|
109
109
|
end
|
110
110
|
|
111
111
|
it 'accepts start_at and max_results options' do
|
@@ -113,10 +113,10 @@ describe JIRA::Resource::Project do
|
|
113
113
|
max_results = rand(1000)
|
114
114
|
|
115
115
|
expect(client).to receive(:get)
|
116
|
-
.with("/jira/rest/api/2/user/assignable/search?project=#{project_key}&startAt=#{start_at}&maxResults=#{max_results}")
|
116
|
+
.with("/jira/rest/api/2/user/assignable/search?project=#{project_key}&startAt=#{start_at}&maxResults=#{max_results}") # rubocop:disable Layout/LineLength
|
117
117
|
.and_return(response)
|
118
118
|
|
119
|
-
project.users(start_at
|
119
|
+
project.users(start_at:, max_results:)
|
120
120
|
end
|
121
121
|
end
|
122
122
|
end
|
@@ -2,19 +2,32 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe JIRA::Resource::Sprint do
|
4
4
|
let(:client) do
|
5
|
-
client = double(options: {
|
5
|
+
client = double(options: { rest_base_path: '/jira/rest/api/2', context_path: '/jira' })
|
6
6
|
allow(client).to receive(:Sprint).and_return(JIRA::Resource::SprintFactory.new(client))
|
7
7
|
client
|
8
8
|
end
|
9
9
|
let(:sprint) { described_class.new(client) }
|
10
|
-
let(:agile_sprint_path) { "
|
10
|
+
let(:agile_sprint_path) { "/jira/rest/agile/1.0/sprint/#{sprint.id}" }
|
11
|
+
let(:response) { double }
|
12
|
+
|
13
|
+
describe 'get_sprint_details' do
|
14
|
+
let(:sprint) { described_class.find(client, '1') }
|
15
|
+
|
16
|
+
it 'check each of the date attributes' do
|
17
|
+
allow(client).to receive(:get).and_return(double(body: get_mock_response('sprint/1.json')))
|
18
|
+
|
19
|
+
expect(sprint.start_date).to eq Date.parse('2024-01-01T03:20:00.000Z')
|
20
|
+
expect(sprint.end_date).to eq Date.parse('2024-01-15T03:20:00.000Z')
|
21
|
+
expect(sprint.complete_date).to eq Date.parse('2024-01-16T03:48:00.000Z')
|
22
|
+
end
|
23
|
+
end
|
11
24
|
|
12
25
|
describe '::find' do
|
13
26
|
let(:response) { double('Response', body: '{"some_detail":"some detail"}') }
|
14
27
|
|
15
28
|
it 'fetches the sprint from JIRA' do
|
16
29
|
expect(client).to receive(:get).with('/jira/rest/agile/1.0/sprint/111').and_return(response)
|
17
|
-
expect(
|
30
|
+
expect(described_class.find(client, '111')).to be_a(described_class)
|
18
31
|
end
|
19
32
|
end
|
20
33
|
|
@@ -86,5 +99,59 @@ describe JIRA::Resource::Sprint do
|
|
86
99
|
end
|
87
100
|
end
|
88
101
|
end
|
102
|
+
|
103
|
+
context 'an issue exists' do
|
104
|
+
let(:issue_id) { 1001 }
|
105
|
+
let(:post_issue_path) do
|
106
|
+
described_class.agile_path(client, sprint.id)
|
107
|
+
'/jira/rest/agile/1.0/sprint//issue'
|
108
|
+
end
|
109
|
+
let(:issue) do
|
110
|
+
issue = double
|
111
|
+
allow(issue).to receive(:id).and_return(issue_id)
|
112
|
+
issue
|
113
|
+
end
|
114
|
+
let(:post_issue_input) do
|
115
|
+
{ issues: [issue.id] }
|
116
|
+
end
|
117
|
+
|
118
|
+
describe '#add_issu' do
|
119
|
+
context 'when an issue is passed' do
|
120
|
+
it 'posts with the issue id' do
|
121
|
+
expect(client).to receive(:post).with(post_issue_path, post_issue_input.to_json)
|
122
|
+
|
123
|
+
sprint.add_issue(issue)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
context 'multiple issues exists' do
|
130
|
+
let(:issue_ids) { [1001, 1012] }
|
131
|
+
let(:post_issue_path) do
|
132
|
+
described_class.agile_path(client, sprint.id)
|
133
|
+
'/jira/rest/agile/1.0/sprint//issue'
|
134
|
+
end
|
135
|
+
let(:issues) do
|
136
|
+
issue_ids.map do |issue_id|
|
137
|
+
issue = double
|
138
|
+
allow(issue).to receive(:id).and_return(issue_id)
|
139
|
+
issue
|
140
|
+
end
|
141
|
+
end
|
142
|
+
let(:post_issue_input) do
|
143
|
+
{ issues: issue_ids }
|
144
|
+
end
|
145
|
+
|
146
|
+
describe '#add_issues' do
|
147
|
+
context 'when an issue is passed' do
|
148
|
+
it 'posts with the issue id' do
|
149
|
+
expect(client).to receive(:post).with(post_issue_path, post_issue_input.to_json)
|
150
|
+
|
151
|
+
sprint.add_issues(issues)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
89
156
|
end
|
90
157
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe JIRA::Resource::Status do
|
4
|
+
let(:client) do
|
5
|
+
client = double(options: { rest_base_path: '/jira/rest/api/2' })
|
6
|
+
allow(client).to receive(:Field).and_return(JIRA::Resource::FieldFactory.new(client))
|
7
|
+
allow(client).to receive(:cache).and_return(OpenStruct.new)
|
8
|
+
client
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '#status_category' do
|
12
|
+
subject do
|
13
|
+
described_class.new(client, attrs: JSON.parse(File.read('spec/mock_responses/status/1.json')))
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'has a status_category relationship' do
|
17
|
+
expect(subject).to have_one(:status_category, JIRA::Resource::StatusCategory)
|
18
|
+
expect(subject.status_category.name).to eq('To Do')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|