jira-ruby 2.3.0 → 3.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +20 -0
  3. data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  4. data/.github/dependabot.yml +6 -0
  5. data/.github/workflows/CI.yml +28 -0
  6. data/.github/workflows/codeql.yml +100 -0
  7. data/.github/workflows/rubocop.yml +18 -0
  8. data/.rubocop.yml +188 -0
  9. data/Gemfile +11 -3
  10. data/Guardfile +2 -0
  11. data/README.md +94 -18
  12. data/Rakefile +3 -4
  13. data/jira-ruby.gemspec +11 -17
  14. data/lib/jira/base.rb +37 -28
  15. data/lib/jira/base_factory.rb +4 -1
  16. data/lib/jira/client.rb +64 -46
  17. data/lib/jira/has_many_proxy.rb +4 -2
  18. data/lib/jira/http_client.rb +17 -13
  19. data/lib/jira/http_error.rb +4 -0
  20. data/lib/jira/jwt_client.rb +18 -42
  21. data/lib/jira/oauth_client.rb +6 -3
  22. data/lib/jira/railtie.rb +2 -0
  23. data/lib/jira/request_client.rb +5 -1
  24. data/lib/jira/resource/agile.rb +7 -9
  25. data/lib/jira/resource/applinks.rb +5 -3
  26. data/lib/jira/resource/attachment.rb +43 -3
  27. data/lib/jira/resource/board.rb +5 -3
  28. data/lib/jira/resource/board_configuration.rb +2 -0
  29. data/lib/jira/resource/comment.rb +2 -0
  30. data/lib/jira/resource/component.rb +2 -0
  31. data/lib/jira/resource/createmeta.rb +3 -1
  32. data/lib/jira/resource/field.rb +9 -4
  33. data/lib/jira/resource/filter.rb +2 -0
  34. data/lib/jira/resource/issue.rb +35 -44
  35. data/lib/jira/resource/issue_picker_suggestions.rb +4 -1
  36. data/lib/jira/resource/issue_picker_suggestions_issue.rb +2 -0
  37. data/lib/jira/resource/issuelink.rb +2 -0
  38. data/lib/jira/resource/issuelinktype.rb +2 -0
  39. data/lib/jira/resource/issuetype.rb +2 -0
  40. data/lib/jira/resource/priority.rb +2 -0
  41. data/lib/jira/resource/project.rb +4 -2
  42. data/lib/jira/resource/rapidview.rb +5 -3
  43. data/lib/jira/resource/remotelink.rb +2 -0
  44. data/lib/jira/resource/resolution.rb +2 -0
  45. data/lib/jira/resource/serverinfo.rb +2 -0
  46. data/lib/jira/resource/sprint.rb +14 -23
  47. data/lib/jira/resource/status.rb +7 -1
  48. data/lib/jira/resource/status_category.rb +10 -0
  49. data/lib/jira/resource/suggested_issue.rb +2 -0
  50. data/lib/jira/resource/transition.rb +2 -0
  51. data/lib/jira/resource/user.rb +3 -1
  52. data/lib/jira/resource/version.rb +2 -0
  53. data/lib/jira/resource/watcher.rb +2 -1
  54. data/lib/jira/resource/webhook.rb +4 -2
  55. data/lib/jira/resource/worklog.rb +3 -2
  56. data/lib/jira/version.rb +3 -1
  57. data/lib/jira-ruby.rb +5 -3
  58. data/lib/tasks/generate.rake +4 -2
  59. data/spec/data/files/short.txt +1 -0
  60. data/spec/integration/attachment_spec.rb +3 -3
  61. data/spec/integration/comment_spec.rb +8 -8
  62. data/spec/integration/component_spec.rb +7 -7
  63. data/spec/integration/field_spec.rb +3 -3
  64. data/spec/integration/issue_spec.rb +20 -16
  65. data/spec/integration/issuelinktype_spec.rb +3 -3
  66. data/spec/integration/issuetype_spec.rb +3 -3
  67. data/spec/integration/priority_spec.rb +3 -3
  68. data/spec/integration/project_spec.rb +7 -7
  69. data/spec/integration/rapidview_spec.rb +9 -9
  70. data/spec/integration/resolution_spec.rb +3 -3
  71. data/spec/integration/status_category_spec.rb +20 -0
  72. data/spec/integration/status_spec.rb +4 -8
  73. data/spec/integration/transition_spec.rb +2 -2
  74. data/spec/integration/user_spec.rb +22 -8
  75. data/spec/integration/version_spec.rb +7 -7
  76. data/spec/integration/watcher_spec.rb +17 -18
  77. data/spec/integration/webhook.rb +5 -4
  78. data/spec/integration/worklog_spec.rb +8 -8
  79. data/spec/jira/base_factory_spec.rb +2 -1
  80. data/spec/jira/base_spec.rb +55 -41
  81. data/spec/jira/client_spec.rb +48 -34
  82. data/spec/jira/has_many_proxy_spec.rb +3 -3
  83. data/spec/jira/http_client_spec.rb +94 -27
  84. data/spec/jira/http_error_spec.rb +2 -2
  85. data/spec/jira/oauth_client_spec.rb +8 -6
  86. data/spec/jira/request_client_spec.rb +4 -4
  87. data/spec/jira/resource/agile_spec.rb +28 -28
  88. data/spec/jira/resource/attachment_spec.rb +142 -52
  89. data/spec/jira/resource/board_spec.rb +21 -20
  90. data/spec/jira/resource/createmeta_spec.rb +48 -48
  91. data/spec/jira/resource/field_spec.rb +30 -12
  92. data/spec/jira/resource/filter_spec.rb +4 -4
  93. data/spec/jira/resource/issue_picker_suggestions_spec.rb +17 -17
  94. data/spec/jira/resource/issue_spec.rb +43 -37
  95. data/spec/jira/resource/jira_picker_suggestions_issue_spec.rb +3 -3
  96. data/spec/jira/resource/project_factory_spec.rb +3 -2
  97. data/spec/jira/resource/project_spec.rb +16 -16
  98. data/spec/jira/resource/sprint_spec.rb +70 -3
  99. data/spec/jira/resource/status_spec.rb +21 -0
  100. data/spec/jira/resource/user_factory_spec.rb +4 -4
  101. data/spec/jira/resource/worklog_spec.rb +3 -3
  102. data/spec/mock_responses/sprint/1.json +13 -0
  103. data/spec/mock_responses/status/1.json +8 -1
  104. data/spec/mock_responses/status.json +40 -5
  105. data/spec/mock_responses/statuscategory/1.json +7 -0
  106. data/spec/mock_responses/statuscategory.json +30 -0
  107. data/spec/mock_responses/{user_username=admin.json → user_accountId=1234567890abcdef01234567.json} +2 -1
  108. data/spec/spec_helper.rb +1 -0
  109. data/spec/support/clients_helper.rb +3 -5
  110. data/spec/support/shared_examples/integration.rb +25 -28
  111. metadata +25 -257
  112. data/.travis.yml +0 -9
  113. data/example.rb +0 -232
  114. data/http-basic-example.rb +0 -113
  115. data/lib/jira/resource/sprint_report.rb +0 -8
  116. data/lib/jira/tasks.rb +0 -0
  117. 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
- JIRA::Resource::Field.new(client, attrs: { 'id' => 'customfield_10666', 'name' => 'Priority', 'custom' => true, 'orderable' => true, 'navigable' => true, 'searchable' => true, 'clauseNames' => ['cf[10666]', 'Priority'], 'schema' => { 'type' => 'string', 'custom' => 'com.atlassian.jira.plugin.system.customfieldtypes:select', 'customId' => 10_666 } }),
14
- JIRA::Resource::Field.new(client, attrs: { 'id' => 'issuekey', 'name' => 'Key', 'custom' => false, 'orderable' => false, 'navigable' => true, 'searchable' => false, 'clauseNames' => %w[id issue issuekey key] }),
15
- JIRA::Resource::Field.new(client, attrs: { 'id' => 'priority', 'name' => 'Priority', 'custom' => false, 'orderable' => true, 'navigable' => true, 'searchable' => true, 'clauseNames' => ['priority'], 'schema' => { 'type' => 'priority', 'system' => 'priority' } }),
16
- JIRA::Resource::Field.new(client, attrs: { 'id' => 'summary', 'name' => 'Summary', 'custom' => false, 'orderable' => true, 'navigable' => true, 'searchable' => true, 'clauseNames' => ['summary'], 'schema' => { 'type' => 'string', 'system' => 'summary' } }),
17
- JIRA::Resource::Field.new(client, attrs: { 'id' => 'issuetype', 'name' => 'Issue Type', 'custom' => false, 'orderable' => true, 'navigable' => true, 'searchable' => true, 'clauseNames' => %w[issuetype type], 'schema' => { 'type' => 'issuetype', 'system' => 'issuetype' } }),
18
- JIRA::Resource::Field.new(client, attrs: { 'id' => 'customfield_10111', 'name' => 'SingleWord', 'custom' => true, 'orderable' => true, 'navigable' => true, 'searchable' => true, 'clauseNames' => ['cf[10111]', 'SingleWord'], 'schema' => { 'type' => 'string', 'custom' => 'com.atlassian.jira.plugin.system.customfieldtypes:select', 'customId' => 10_111 } }),
19
- JIRA::Resource::Field.new(client, attrs: { 'id' => 'customfield_10222', 'name' => 'Multi Word', 'custom' => true, 'orderable' => true, 'navigable' => true, 'searchable' => true, 'clauseNames' => ['cf[10222]', 'Multi Word'], 'schema' => { 'type' => 'string', 'custom' => 'com.atlassian.jira.plugin.system.customfieldtypes:select', 'customId' => 10_222 } }),
20
- JIRA::Resource::Field.new(client, attrs: { 'id' => 'customfield_10333', 'name' => 'Why/N@t', 'custom' => true, 'orderable' => true, 'navigable' => true, 'searchable' => true, 'clauseNames' => ['cf[10333]', 'Why/N@t'], 'schema' => { 'type' => 'string', 'custom' => 'com.atlassian.jira.plugin.system.customfieldtypes:select', 'customId' => 10_333 } }),
21
- JIRA::Resource::Field.new(client, attrs: { 'id' => 'customfield_10444', 'name' => 'SingleWord', 'custom' => true, 'orderable' => true, 'navigable' => true, 'searchable' => true, 'clauseNames' => ['cf[10444]', 'SingleWord'], 'schema' => { 'type' => 'string', 'custom' => 'com.atlassian.jira.plugin.system.customfieldtypes:select', 'customId' => 10_444 } })
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
- JIRA::Resource::Field.new(client, attrs: {
30
- 'priority' => 1,
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
- expect(client).to receive(:get).with("#{collection_path}/42").and_return(filter_response)
52
- allow(JIRA::Resource::Filter).to receive(:collection_path).and_return(collection_path)
53
- JIRA::Resource::Filter.find(client, 42)
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 eql(1)
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
- rest_base_path: '/jira/rest/api/2'
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
- JIRA::Resource::IssuePickerSuggestions.new(client, attrs: {
13
- 'sections' => [{ 'id' => 'hs'}, { 'id' => 'cs' }]
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,7 +30,7 @@ describe JIRA::Resource::IssuePickerSuggestions do
30
30
  allow(issue_picker_suggestions).to receive(:build)
31
31
  end
32
32
 
33
- it 'should autocomplete issues' do
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)
@@ -38,42 +38,42 @@ describe JIRA::Resource::IssuePickerSuggestions do
38
38
  expect(client).to receive(:IssuePickerSuggestions).and_return(issue_picker_suggestions)
39
39
  expect(issue_picker_suggestions).to receive(:build).with({ 'sections' => [{ 'id' => 'cs' }] })
40
40
 
41
- JIRA::Resource::IssuePickerSuggestions.all(client, 'query')
41
+ described_class.all(client, 'query')
42
42
  end
43
43
 
44
- it 'should autocomplete issues with current jql' do
44
+ it 'autocompletes issues with current jql' do
45
45
  expect(client).to receive(:get).with('/jira/rest/api/2/issue/picker?query=query&currentJQL=project+%3D+PR')
46
46
  .and_return(response)
47
47
 
48
- JIRA::Resource::IssuePickerSuggestions.all(client, 'query', current_jql: 'project = PR')
48
+ described_class.all(client, 'query', current_jql: 'project = PR')
49
49
  end
50
50
 
51
- it 'should autocomplete issues with current issue jey' do
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&currentIssueKey=PR-42')
53
53
  .and_return(response)
54
54
 
55
- JIRA::Resource::IssuePickerSuggestions.all(client, 'query', current_issue_key: 'PR-42')
55
+ described_class.all(client, 'query', current_issue_key: 'PR-42')
56
56
  end
57
57
 
58
- it 'should autocomplete issues with current project id' do
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&currentProjectId=PR')
60
60
  .and_return(response)
61
61
 
62
- JIRA::Resource::IssuePickerSuggestions.all(client, 'query', current_project_id: 'PR')
62
+ described_class.all(client, 'query', current_project_id: 'PR')
63
63
  end
64
64
 
65
- it 'should autocomplete issues with show sub tasks' do
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
- JIRA::Resource::IssuePickerSuggestions.all(client, 'query', show_sub_tasks: true)
69
+ described_class.all(client, 'query', show_sub_tasks: true)
70
70
  end
71
71
 
72
- it 'should autocomplete issues with show sub tasks parent' do
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
- JIRA::Resource::IssuePickerSuggestions.all(client, 'query', show_sub_task_parent: true)
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(:each) do
16
+ before do
17
17
  response = double
18
18
  allow(response).to receive(:body).and_return('{"key":"foo","id":"101"}')
19
- allow(JIRA::Resource::Issue).to receive(:collection_path).and_return('/jira/rest/api/2/issue')
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 = JIRA::Resource::Issue.find(client, 101)
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 'should find all issues' do
39
+ it 'finds all issues' do
38
40
  response = double
39
41
  empty_response = double
40
42
  issue = double
@@ -49,26 +51,26 @@ describe JIRA::Resource::Issue do
49
51
  expect(client).to receive(:Issue).and_return(issue)
50
52
  expect(issue).to receive(:build).with({ 'id' => '1', 'summary' => 'Bugs Everywhere' })
51
53
 
52
- issues = JIRA::Resource::Issue.all(client)
54
+ issues = described_class.all(client)
53
55
  end
54
56
 
55
- it 'should find an issue by key or id' do
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(JIRA::Resource::Issue).to receive(:collection_path).and_return('/jira/rest/api/2/issue')
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 = JIRA::Resource::Issue.find(client, 101)
66
- issue_from_key = JIRA::Resource::Issue.find(client, 'foo')
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 'should search an issue with a jql query string' do
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(JIRA::Resource::Issue.jql(client, 'foo bar')).to eq([''])
83
+ expect(described_class.jql(client, 'foo bar')).to eq([''])
82
84
  end
83
85
 
84
- it 'should search an issue with a jql query string and fields' do
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(JIRA::Resource::Issue.jql(client, 'foo bar', fields: %w[foo bar])).to eq([''])
97
+ expect(described_class.jql(client, 'foo bar', fields: %w[foo bar])).to eq([''])
96
98
  end
97
99
 
98
- it 'should search an issue with a jql query string, start at, and maxResults' do
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(JIRA::Resource::Issue.jql(client, 'foo bar', start_at: 1, max_results: 3)).to eq([''])
111
+ expect(described_class.jql(client, 'foo bar', start_at: 1, max_results: 3)).to eq([''])
110
112
  end
111
113
 
112
- it 'should search an issue with a jql query string and maxResults equals zero and should return the count of tickets' do
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(JIRA::Resource::Issue.jql(client, 'foo bar', max_results: 0)).to eq(1)
123
+ expect(described_class.jql(client, 'foo bar', max_results: 0)).to eq(1)
122
124
  end
123
125
 
124
- it 'should search an issue with a jql query string and string expand' do
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(JIRA::Resource::Issue.jql(client, 'foo bar', expand: 'transitions')).to eq([''])
137
+ expect(described_class.jql(client, 'foo bar', expand: 'transitions')).to eq([''])
136
138
  end
137
139
 
138
- it 'should search an issue with a jql query string and array expand' do
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(JIRA::Resource::Issue.jql(client, 'foo bar', expand: %w[transitions])).to eq([''])
151
+ expect(described_class.jql(client, 'foo bar', expand: %w[transitions])).to eq([''])
150
152
  end
151
153
 
152
- it 'should return meta data available for editing an issue' do
153
- subject = JIRA::Resource::Issue.new(client, attrs: { 'fields' => { 'key' => 'TST=123' } })
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 = JIRA::Resource::Issue.new(client, attrs: { 'fields' => { 'foo' => 'bar' } })
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
- JIRA::Resource::Issue.new(client, attrs: {
175
- 'id' => '123',
176
+ described_class.new(client, attrs: {
177
+ 'id' => '123',
176
178
  'fields' => {
177
179
  'reporter' => { 'foo' => 'bar' },
178
- 'assignee' => { 'foo' => 'bar' },
179
- 'project' => { 'foo' => 'bar' },
180
- 'priority' => { 'foo' => 'bar' },
181
- 'issuetype' => { 'foo' => 'bar' },
182
- 'status' => { 'foo' => 'bar' },
183
- 'components' => [{ 'foo' => 'bar' }, { 'baz' => 'flum' }],
184
- 'versions' => [{ 'foo' => 'bar' }, { 'baz' => 'flum' }],
185
- 'comment' => { 'comments' => [{ 'foo' => 'bar' }, { 'baz' => 'flum' }] },
186
- 'attachment' => [{ 'foo' => 'bar' }, { 'baz' => 'flum' }],
187
- 'worklog' => { 'worklogs' => [{ 'foo' => 'bar' }, { 'baz' => 'flum' }] }
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
- JIRA::Resource::IssuePickerSuggestionsIssue.new(client, attrs: {
9
- 'issues' => [{ 'id' => '1'}, { 'id' => '2' }]
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(JIRA::Resource::ProjectFactory)
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
- JIRA::Resource::Project.new(client, attrs: {
13
- 'lead' => { 'foo' => 'bar' },
14
- 'issueTypes' => [{ 'foo' => 'bar' }, { 'baz' => 'flum' }],
15
- 'versions' => [{ 'foo' => 'bar' }, { 'baz' => 'flum' }]
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
- JIRA::Resource::Project.new(client, attrs: {
34
- 'key' => 'test'
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) { JIRA::Resource::Project.new(client, attrs: { 'key' => project_key }) }
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(:each) do
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: 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: 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: start_at, max_results: max_results)
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: { site: 'https://foo.bar.com', context_path: '/jira' })
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) { "#{sprint.client.options[:context_path]}/rest/agile/1.0/sprint/#{sprint.id}" }
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(JIRA::Resource::Sprint.find(client, '111')).to be_a(JIRA::Resource::Sprint)
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