jira-auto-tool 0.1.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.
Files changed (139) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +291 -0
  4. data/CHANGELOG.md +5 -0
  5. data/CODE_OF_CONDUCT.md +132 -0
  6. data/Guardfile +105 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +159 -0
  9. data/Rakefile +20 -0
  10. data/bin/jira-auto-tool +57 -0
  11. data/bin/jira-auto-tool.bat +2 -0
  12. data/bin/setup +8 -0
  13. data/bin/setup-dev-win.bat +3 -0
  14. data/cucumber.yml +7 -0
  15. data/features/align_sprint_time_in_dates.feature +33 -0
  16. data/features/assign_tickets_to_team_sprints.feature +73 -0
  17. data/features/cache_boards.feature +24 -0
  18. data/features/control_http_request_rate_limit.feature +17 -0
  19. data/features/create_sprints_using_existing_ones_as_reference.feature +79 -0
  20. data/features/list_boards.feature +12 -0
  21. data/features/list_project_fields.feature +89 -0
  22. data/features/list_sprint_prefixes.feature +77 -0
  23. data/features/quarterly_add_sprints_using_existing_ones_as_a_reference.feature +71 -0
  24. data/features/quarterly_create_sprints_until_specific_date.feature +75 -0
  25. data/features/quarterly_rename_sprints.feature +179 -0
  26. data/features/rename_sprints.feature +203 -0
  27. data/features/self_documented_command_line.feature +15 -0
  28. data/features/sprint_filtering.feature +111 -0
  29. data/features/step_definitions/execution_context_steps.rb +33 -0
  30. data/features/step_definitions/jira_board_steps.rb +102 -0
  31. data/features/step_definitions/jira_ticket_steps.rb +63 -0
  32. data/features/support/10.setup_cucumber.rb +10 -0
  33. data/features/support/env.rb +25 -0
  34. data/features/support/hooks.rb +25 -0
  35. data/features/support/setup_rspec.rb +14 -0
  36. data/features/support/setup_simplecov.rb +5 -0
  37. data/features/update_sprint_end_date_and_shift_following_ones.feature +52 -0
  38. data/lib/jira/auto/tool/board/cache.rb +67 -0
  39. data/lib/jira/auto/tool/board/unavailable_board.rb +36 -0
  40. data/lib/jira/auto/tool/board.rb +105 -0
  41. data/lib/jira/auto/tool/board_controller/options.rb +32 -0
  42. data/lib/jira/auto/tool/board_controller.rb +88 -0
  43. data/lib/jira/auto/tool/common_options.rb +37 -0
  44. data/lib/jira/auto/tool/config/options.rb +19 -0
  45. data/lib/jira/auto/tool/config.rb +64 -0
  46. data/lib/jira/auto/tool/fetch_custom_field_options.rb +47 -0
  47. data/lib/jira/auto/tool/field.rb +59 -0
  48. data/lib/jira/auto/tool/field_controller.rb +50 -0
  49. data/lib/jira/auto/tool/field_option.rb +35 -0
  50. data/lib/jira/auto/tool/get_createmeta_for_project.rb +24 -0
  51. data/lib/jira/auto/tool/helpers/environment_based_value.rb +96 -0
  52. data/lib/jira/auto/tool/helpers/option_parser.rb +16 -0
  53. data/lib/jira/auto/tool/helpers/overridable_time.rb +18 -0
  54. data/lib/jira/auto/tool/helpers/pagination.rb +50 -0
  55. data/lib/jira/auto/tool/jira_http_options.rb +20 -0
  56. data/lib/jira/auto/tool/next_sprint_creator.rb +60 -0
  57. data/lib/jira/auto/tool/performer/options.rb +76 -0
  58. data/lib/jira/auto/tool/performer/planning_increment_sprint_creator.rb +42 -0
  59. data/lib/jira/auto/tool/performer/prefix_sprint_updater.rb +42 -0
  60. data/lib/jira/auto/tool/performer/quarterly_sprint_renamer/next_name_generator.rb +60 -0
  61. data/lib/jira/auto/tool/performer/quarterly_sprint_renamer.rb +19 -0
  62. data/lib/jira/auto/tool/performer/sprint_end_date_updater.rb +55 -0
  63. data/lib/jira/auto/tool/performer/sprint_renamer/keep_same_name_generator.rb +19 -0
  64. data/lib/jira/auto/tool/performer/sprint_renamer/next_name_generator.rb +47 -0
  65. data/lib/jira/auto/tool/performer/sprint_renamer.rb +55 -0
  66. data/lib/jira/auto/tool/performer/sprint_time_in_dates_aligner.rb +52 -0
  67. data/lib/jira/auto/tool/project/options.rb +22 -0
  68. data/lib/jira/auto/tool/project/ticket_fields.rb +70 -0
  69. data/lib/jira/auto/tool/project.rb +40 -0
  70. data/lib/jira/auto/tool/rate_limited_jira_client.rb +50 -0
  71. data/lib/jira/auto/tool/request_builder/field_context_fetcher.rb +78 -0
  72. data/lib/jira/auto/tool/request_builder/field_option_fetcher.rb +54 -0
  73. data/lib/jira/auto/tool/request_builder/get.rb +29 -0
  74. data/lib/jira/auto/tool/request_builder/sprint_creator.rb +112 -0
  75. data/lib/jira/auto/tool/request_builder/sprint_state_updater.rb +60 -0
  76. data/lib/jira/auto/tool/request_builder.rb +89 -0
  77. data/lib/jira/auto/tool/setup_logging.rb +35 -0
  78. data/lib/jira/auto/tool/sprint/name.rb +105 -0
  79. data/lib/jira/auto/tool/sprint/prefix.rb +66 -0
  80. data/lib/jira/auto/tool/sprint.rb +183 -0
  81. data/lib/jira/auto/tool/sprint_controller/options.rb +61 -0
  82. data/lib/jira/auto/tool/sprint_controller.rb +152 -0
  83. data/lib/jira/auto/tool/sprint_state_controller.rb +58 -0
  84. data/lib/jira/auto/tool/team.rb +23 -0
  85. data/lib/jira/auto/tool/team_sprint_prefix_mapper/options.rb +27 -0
  86. data/lib/jira/auto/tool/team_sprint_prefix_mapper.rb +62 -0
  87. data/lib/jira/auto/tool/team_sprint_ticket_dispatcher.rb +76 -0
  88. data/lib/jira/auto/tool/ticket.rb +110 -0
  89. data/lib/jira/auto/tool/until_date.rb +68 -0
  90. data/lib/jira/auto/tool/version.rb +9 -0
  91. data/lib/jira/auto/tool.rb +216 -0
  92. data/sig/jira/sprint/tool.rbs +8 -0
  93. data/spec/jira/auto/tool/board/cache_spec.rb +179 -0
  94. data/spec/jira/auto/tool/board/unavailable_board_spec.rb +34 -0
  95. data/spec/jira/auto/tool/board_controller/options_spec.rb +52 -0
  96. data/spec/jira/auto/tool/board_controller_spec.rb +154 -0
  97. data/spec/jira/auto/tool/board_spec.rb +163 -0
  98. data/spec/jira/auto/tool/common_options_spec.rb +49 -0
  99. data/spec/jira/auto/tool/config_spec.rb +108 -0
  100. data/spec/jira/auto/tool/field_controller_spec.rb +121 -0
  101. data/spec/jira/auto/tool/field_option_spec.rb +42 -0
  102. data/spec/jira/auto/tool/field_spec.rb +99 -0
  103. data/spec/jira/auto/tool/helpers/environment_based_value_spec.rb +21 -0
  104. data/spec/jira/auto/tool/helpers/option_parser_spec.rb +21 -0
  105. data/spec/jira/auto/tool/helpers/overridable_time_spec.rb +43 -0
  106. data/spec/jira/auto/tool/helpers/pagination_spec.rb +72 -0
  107. data/spec/jira/auto/tool/jira_http_options_spec.rb +32 -0
  108. data/spec/jira/auto/tool/next_sprint_creator_spec.rb +85 -0
  109. data/spec/jira/auto/tool/performer/option_spec.rb +55 -0
  110. data/spec/jira/auto/tool/performer/planning_increment_sprint_creator_spec.rb +62 -0
  111. data/spec/jira/auto/tool/performer/prefix_sprint_updater_spec.rb +35 -0
  112. data/spec/jira/auto/tool/performer/quarterly_sprint_renamer/next_name_generator_spec.rb +175 -0
  113. data/spec/jira/auto/tool/performer/quarterly_sprint_renamer_spec.rb +239 -0
  114. data/spec/jira/auto/tool/performer/sprint_end_date_updater_spec.rb +90 -0
  115. data/spec/jira/auto/tool/performer/sprint_renamer/keep_same_name_generator_spec.rb +12 -0
  116. data/spec/jira/auto/tool/performer/sprint_renamer/next_name_generator_spec.rb +129 -0
  117. data/spec/jira/auto/tool/performer/sprint_renamer_spec.rb +240 -0
  118. data/spec/jira/auto/tool/performer/sprint_time_in_dates_aligner_spec.rb +132 -0
  119. data/spec/jira/auto/tool/project/ticket_fields_spec.rb +390 -0
  120. data/spec/jira/auto/tool/project_spec.rb +31 -0
  121. data/spec/jira/auto/tool/rate_limited_jira_client_spec.rb +82 -0
  122. data/spec/jira/auto/tool/request_builder/field_context_fetcher_spec.rb +54 -0
  123. data/spec/jira/auto/tool/request_builder/field_option_fetcher_spec.rb +64 -0
  124. data/spec/jira/auto/tool/request_builder/get_spec.rb +40 -0
  125. data/spec/jira/auto/tool/request_builder/sprint_creator_spec.rb +179 -0
  126. data/spec/jira/auto/tool/request_builder/sprint_state_updater_spec.rb +31 -0
  127. data/spec/jira/auto/tool/request_builder_spec.rb +73 -0
  128. data/spec/jira/auto/tool/sprint/name_spec.rb +101 -0
  129. data/spec/jira/auto/tool/sprint/prefix_spec.rb +207 -0
  130. data/spec/jira/auto/tool/sprint_controller_spec.rb +406 -0
  131. data/spec/jira/auto/tool/sprint_spec.rb +309 -0
  132. data/spec/jira/auto/tool/team_spec.rb +21 -0
  133. data/spec/jira/auto/tool/team_sprint_prefix_mapper_spec.rb +97 -0
  134. data/spec/jira/auto/tool/team_sprint_ticket_dispatcher_spec.rb +232 -0
  135. data/spec/jira/auto/tool/ticket_spec.rb +116 -0
  136. data/spec/jira/auto/tool/until_date_spec.rb +80 -0
  137. data/spec/jira/auto/tool_spec.rb +458 -0
  138. data/spec/spec_helper.rb +42 -0
  139. metadata +368 -0
@@ -0,0 +1,406 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "jira/auto/tool/sprint_controller"
4
+
5
+ module Jira
6
+ module Auto
7
+ # rubocop:disable Metrics/ClassLength
8
+ class Tool
9
+ RSpec.describe SprintController do
10
+ let(:tool) { instance_double(Tool) }
11
+ let(:board) { double(JIRA::Resource::Board, name: "board name", id: 128) } # rubocop:disable RSpec/VerifiedDoubles
12
+ let(:sprint_controller) { described_class.new(tool, board) }
13
+
14
+ describe "#quarterly_add_sprints_until" do
15
+ let(:actual_sprint_prefixes) do
16
+ %w[art_team1 art_team2 art_team3].collect do |name_prefix|
17
+ instance_double(Sprint::Prefix, name: name_prefix, quarterly_add_sprints_until: nil)
18
+ end
19
+ end
20
+
21
+ it "creates sprints for all unclosed prefixes until date is included" do
22
+ allow(sprint_controller).to receive_messages(unclosed_sprint_prefixes: actual_sprint_prefixes)
23
+
24
+ sprint_controller.quarterly_add_sprints_until("2024-05-15")
25
+
26
+ expect(actual_sprint_prefixes).to all have_received(:quarterly_add_sprints_until).with("2024-05-15")
27
+ end
28
+ end
29
+
30
+ describe "#quarterly_add_one_sprint_for_each_unclosed_sprint_prefix" do
31
+ context "when no sprint are found" do
32
+ it "exits with a warning" do
33
+ allow(sprint_controller).to receive_messages(sprints: [])
34
+ allow(sprint_controller).to receive_messages(exit_with_board_warning: nil)
35
+
36
+ sprint_controller.quarterly_add_one_sprint_for_each_unclosed_sprint_prefix
37
+
38
+ expect(sprint_controller).to have_received(:exit_with_board_warning)
39
+ .with("No sprint added since no reference sprint was found!")
40
+ end
41
+ end
42
+
43
+ context "when only closed sprint are found" do
44
+ let(:closed_sprints) do
45
+ [[1, "1st sprint"], [2, "2nd sprint"]]
46
+ .collect { |id, name| double(JIRA::Resource::Sprint, id: id, name: name, state: "closed") } # rubocop:disable RSpec/VerifiedDoubles
47
+ end
48
+
49
+ it "exits with a warning" do
50
+ allow(sprint_controller).to receive_messages(jira_sprints: closed_sprints)
51
+ allow(sprint_controller).to receive_messages(exit_with_board_warning: nil)
52
+
53
+ sprint_controller.quarterly_add_one_sprint_for_each_unclosed_sprint_prefix
54
+
55
+ expect(sprint_controller).to have_received(:exit_with_board_warning)
56
+ .with("No sprint added since no unclosed reference sprint was found!")
57
+ end
58
+ end
59
+
60
+ context "when unclosed sprint are found" do
61
+ let(:actual_sprint_prefixes) do
62
+ ["1st sprint_prefix", "3rd sprint_prefix"].collect do |prefix_name|
63
+ instance_double(Sprint::Prefix, name: prefix_name, add_sprint_following_last_one: nil)
64
+ end
65
+ end
66
+
67
+ it "add a sprint for the sprint prefixes having at least one unclosed sprint" do
68
+ allow(sprint_controller).to receive_messages(sprint_exist?: true, unclosed_sprint_exist?: true)
69
+ allow(sprint_controller).to receive_messages(unclosed_sprint_prefixes: actual_sprint_prefixes)
70
+
71
+ sprint_controller.quarterly_add_one_sprint_for_each_unclosed_sprint_prefix
72
+
73
+ expect(actual_sprint_prefixes).to all have_received(:add_sprint_following_last_one)
74
+ end
75
+ end
76
+ end
77
+
78
+ describe "#sprints" do
79
+ let(:jira_sprints) do
80
+ [
81
+ [1, "ART-16_E2E-Test_24.4.1"],
82
+ [2, "ART-16_CRM_24.4.1"],
83
+ [3, "ART-16_E2E-Test_24.4.2"],
84
+ [4, "ART-32_Platform_24.4.7"],
85
+ [5, "ART-32_Sys-Team_24.4.12"],
86
+ [6, "ART-32_Sys-Team_25.1.1"],
87
+ [2, "ART-16_CRM_24.4.1"],
88
+ [3, "ART-16_E2E-Test_24.4.2"]
89
+ ].collect { |id, name| jira_resource_double(Sprint, id: id, name: name) }
90
+ end
91
+
92
+ before do
93
+ allow(sprint_controller).to receive_messages(jira_sprints: jira_sprints)
94
+ end
95
+
96
+ it "returns the sprints" do
97
+ expect(sprint_controller.sprints).to all be_a(Sprint)
98
+ end
99
+
100
+ it "eliminates duplicates (e.g., related to a sprint showing up on several boards)" do
101
+ expect(sprint_controller.sprints.collect(&:name)).to eq(%w[
102
+ ART-16_CRM_24.4.1
103
+ ART-16_E2E-Test_24.4.1
104
+ ART-16_E2E-Test_24.4.2
105
+ ART-32_Platform_24.4.7
106
+ ART-32_Sys-Team_24.4.12
107
+ ART-32_Sys-Team_25.1.1
108
+ ])
109
+ end
110
+
111
+ context "when looking at the sprint order" do
112
+ let(:jira_sprints) do
113
+ [
114
+ [16, "ART-32_Sys-Team_24.4.2", 7, "2024-05-15", "2024-05-22"],
115
+ [32, "1st sprint", 14, "2024-05-01", "2024-05-15"],
116
+ [64, "2nd sprint", 7, "2024-05-15", "2024-05-22"],
117
+ [128, "Non compliant sprint name", 7, "2024-05-15", "2024-05-22"],
118
+ [256, "ART-16_E2E_25.1.2", 7, "2024-05-15", "2024-05-22"]
119
+ ].collect do |id, name, _length_in_days, start_date, end_date|
120
+ jira_resource_double(JIRA::Resource::Sprint, id: id, name: name, startDate: start_date,
121
+ endDate: end_date)
122
+ end
123
+ end
124
+
125
+ let(:expected_sorted_sprint_names) do
126
+ [
127
+ "1st sprint",
128
+ "2nd sprint",
129
+ "ART-16_E2E_25.1.2",
130
+ "ART-32_Sys-Team_24.4.2",
131
+ "Non compliant sprint name"
132
+ ]
133
+ end
134
+
135
+ before do
136
+ allow(sprint_controller).to receive_messages(jira_sprints: jira_sprints)
137
+ end
138
+
139
+ it "returns sorted sprints" do
140
+ expect(sprint_controller.sprints.collect(&:name)).to eq(expected_sorted_sprint_names)
141
+ end
142
+ end
143
+ end
144
+
145
+ describe "#list_sprints" do
146
+ let(:matching_sprints) do
147
+ [
148
+ ["1st sprint", 14, "2024-05-01", "2024-05-15", "board info 1", "board info 2"],
149
+ ["2nd sprint", 7, "2024-05-15", "2024-05-22", "board info 3", "board info 4"]
150
+ ]
151
+ .collect { |row_info| instance_double(Sprint, to_table_row: row_info, state: "future") }
152
+ end
153
+
154
+ let(:expected_sprint_table) do
155
+ <<~END_OF_TABLE
156
+ +---------------------------------------------------------------------------------------+
157
+ | Matching Sprints |
158
+ +------------+----------------+------------+------------+---------------+---------------+
159
+ | Sprint | Length In Days | Start Date | End Date | Board Column1 | Board Column2 |
160
+ +------------+----------------+------------+------------+---------------+---------------+
161
+ | 1st sprint | 14 | 2024-05-01 | 2024-05-15 | board info 1 | board info 2 |
162
+ | 2nd sprint | 7 | 2024-05-15 | 2024-05-22 | board info 3 | board info 4 |
163
+ +------------+----------------+------------+------------+---------------+---------------+
164
+ END_OF_TABLE
165
+ end
166
+
167
+ before do
168
+ allow(sprint_controller).to receive_messages(sprints: matching_sprints)
169
+ end
170
+
171
+ it "list the matching sprints as a table" do
172
+ allow(Sprint).to receive_messages(
173
+ to_table_row_header: ["Sprint", "Length In Days", "Start Date", "End Date",
174
+ "Board Column1", "Board Column2"]
175
+ )
176
+ expect { sprint_controller.list_sprints }.to output(expected_sprint_table).to_stdout
177
+ end
178
+
179
+ it "can be called so that the board information is excluded" do
180
+ allow(Sprint).to receive(:to_table_row_header).with(without_board_information: true).and_return([:name])
181
+
182
+ expect(matching_sprints).to all receive(:to_table_row).with(without_board_information: true)
183
+
184
+ allow($stdout).to receive_messages(puts: nil)
185
+
186
+ sprint_controller.list_sprints(without_board_information: true)
187
+ end
188
+ end
189
+
190
+ describe "#list_sprint_prefixes" do
191
+ let(:sprint_prefixes) do
192
+ [
193
+ ["Food_Delivery", "Food_Delivery_25.2.3", 7, "2024-05-15", "2024-05-22", "board info 3", "board info 4"],
194
+ ["Food_Supply", "Food_Supply_25.2.2", 14, "2024-05-01", "2024-05-15", "board info 1", "board info 2"]
195
+ ]
196
+ .collect { |row_info| instance_double(Sprint::Prefix, to_table_row: row_info) }
197
+ end
198
+
199
+ let(:expected_sprint_prefix_table) do
200
+ <<~END_OF_TABLE
201
+ +-----------------------------------------------------------------------------------------------------------------+
202
+ | Sprint Prefixes With Corresponding Last Sprints |
203
+ +---------------+----------------------+----------------+------------+------------+---------------+---------------+
204
+ | Sprint Prefix | Last Sprint Name | Length In Days | Start Date | End Date | Board Column1 | Board Column2 |
205
+ +---------------+----------------------+----------------+------------+------------+---------------+---------------+
206
+ | Food_Delivery | Food_Delivery_25.2.3 | 7 | 2024-05-15 | 2024-05-22 | board info 3 | board info 4 |
207
+ | Food_Supply | Food_Supply_25.2.2 | 14 | 2024-05-01 | 2024-05-15 | board info 1 | board info 2 |
208
+ +---------------+----------------------+----------------+------------+------------+---------------+---------------+
209
+ END_OF_TABLE
210
+ end
211
+
212
+ before { allow(sprint_controller).to receive_messages(unclosed_sprint_prefixes: sprint_prefixes) }
213
+
214
+ it "list the sprint prefixes as a table" do
215
+ allow(Sprint::Prefix).to receive_messages(
216
+ to_table_row_header: ["Sprint Prefix", "Last Sprint Name", "Length In Days", "Start Date", "End Date",
217
+ "Board Column1", "Board Column2"]
218
+ )
219
+
220
+ expect { sprint_controller.list_sprint_prefixes }.to output(expected_sprint_prefix_table).to_stdout
221
+ end
222
+
223
+ it "can be called so that the board information is excluded" do
224
+ allow(Sprint::Prefix)
225
+ .to receive(:to_table_row_header).with(without_board_information: true).and_return([:name])
226
+
227
+ expect(sprint_prefixes).to all receive(:to_table_row).with(without_board_information: true)
228
+
229
+ allow($stdout).to receive_messages(puts: nil)
230
+
231
+ sprint_controller.list_sprint_prefixes(without_board_information: true)
232
+ end
233
+ end
234
+
235
+ describe "#jira_sprints" do
236
+ let(:all_sprints) do
237
+ %w[
238
+ ART-16_E2E-Test_24.4.1
239
+ ART-16_CRM_24.4.1
240
+ ART-16_E2E-Test_24.4.2
241
+ ART-32_Platform_24.4.7
242
+ ART-32_Sys-Team_24.4.12
243
+ ART-32_Sys-Team_25.1.1
244
+ ].collect { |name| jira_resource_double(Sprint, name: name) }
245
+ end
246
+ let(:art_sprint_regex_defined?) { false }
247
+ let(:art_sprint_regex) { nil }
248
+
249
+ before do
250
+ allow(tool)
251
+ .to receive_messages(art_sprint_regex_defined?: art_sprint_regex_defined?,
252
+ art_sprint_regex: art_sprint_regex)
253
+
254
+ allow(sprint_controller).to receive_messages(unfiltered_board_sprints: all_sprints)
255
+ end
256
+
257
+ context "when no filter specified" do
258
+ it { expect(sprint_controller.jira_sprints).to eq(all_sprints) }
259
+ end
260
+
261
+ context "when filter specified" do
262
+ let(:art_sprint_regex_defined?) { true }
263
+
264
+ context "when using a string" do
265
+ let(:art_sprint_regex) { "ART-16" }
266
+
267
+ it do
268
+ expect(sprint_controller.jira_sprints.collect(&:name))
269
+ .to eq(%w[
270
+ ART-16_E2E-Test_24.4.1
271
+ ART-16_CRM_24.4.1
272
+ ART-16_E2E-Test_24.4.2
273
+ ])
274
+ end
275
+ end
276
+
277
+ context "when using a regex" do
278
+ let(:art_sprint_regex) { "E2E|Sys" }
279
+
280
+ it do
281
+ expect(sprint_controller.jira_sprints.collect(&:name))
282
+ .to eq(%w[
283
+ ART-16_E2E-Test_24.4.1
284
+ ART-16_E2E-Test_24.4.2
285
+ ART-32_Sys-Team_24.4.12
286
+ ART-32_Sys-Team_25.1.1
287
+ ])
288
+ end
289
+ end
290
+ end
291
+ end
292
+
293
+ describe "#unclosed_sprint_prefixes" do
294
+ def new_jira_sprints(name_start_end_trios)
295
+ name_start_end_trios.collect do |id, name, start_data, end_date|
296
+ jira_resource_double(JIRA::Resource::Sprint,
297
+ id: id, name: name, startDate: start_data, endDate: end_date, state: "future")
298
+ end
299
+ end
300
+
301
+ def new_sprints(jira_sprints)
302
+ jira_sprints.collect { |jira_sprint| Sprint.new(tool, jira_sprint) }
303
+ end
304
+
305
+ let(:e2e_jira_sprints) do
306
+ new_jira_sprints [
307
+ [1, "art_e2e_25.1.2", "2024-12-08", "2024-12-14"]
308
+ ]
309
+ end
310
+
311
+ let(:sys_jira_sprints) do
312
+ new_jira_sprints [
313
+ [2, "art_sys_24.4.8", "2024-12-15", "2024-12-22"],
314
+ [3, "art_sys_24.4.9", "2024-12-22", "2024-12-29"]
315
+ ]
316
+ end
317
+
318
+ let(:jira_sprints) { sys_jira_sprints + e2e_jira_sprints }
319
+
320
+ let(:art_e2e_prefix) { Sprint::Prefix.new("art_e2e", new_sprints(e2e_jira_sprints)) }
321
+ let(:art_sys_prefix) { Sprint::Prefix.new("art_sys", new_sprints(sys_jira_sprints)) }
322
+
323
+ it "groups sprints as per their prefix" do
324
+ allow(sprint_controller).to receive_messages(jira_sprints: jira_sprints)
325
+
326
+ expect(sprint_controller.unclosed_sprint_prefixes).to contain_exactly(art_e2e_prefix, art_sys_prefix)
327
+ end
328
+
329
+ it "provides the sprint prefixes sorted by their name" do
330
+ allow(sprint_controller)
331
+ .to receive_messages(calculate_unclosed_sprint_prefixes: [art_sys_prefix, art_e2e_prefix])
332
+
333
+ expect(sprint_controller.unclosed_sprint_prefixes.collect(&:name)).to eq(%w[art_e2e art_sys])
334
+ end
335
+ end
336
+
337
+ describe "#sprint_exist?" do
338
+ let(:examples) do
339
+ [
340
+ [true, %w[sprint_1 sprint_2]],
341
+ [false, []]
342
+ ]
343
+ end
344
+
345
+ it "behaves as expected" do
346
+ examples.each do |expected_result, sprints|
347
+ allow(sprint_controller).to receive_messages(sprints: sprints)
348
+
349
+ expect(sprint_controller.sprint_exist?).to eq(expected_result)
350
+ end
351
+ end
352
+ end
353
+
354
+ describe "#sprint_compatible_boards" do
355
+ let(:boards) do
356
+ [
357
+ ["scrum board_1", true],
358
+ ["kanban board_2", false],
359
+ ["scrum board_3", true],
360
+ ["simple board_4", false]
361
+ ].collect do |name, sprint_compatible|
362
+ instance_double(Board, name: name, sprint_compatible?: sprint_compatible)
363
+ end
364
+ end
365
+
366
+ before { allow(sprint_controller).to receive_messages(boards: boards) }
367
+
368
+ it { expect(sprint_controller.sprint_compatible_boards).to all be_sprint_compatible }
369
+ end
370
+
371
+ describe "#unfiltered_jira_sprints" do
372
+ it "deals with JIRA::Resource pagination" do
373
+ allow(sprint_controller)
374
+ .to receive(:fetch_jira_sprints).with(board,
375
+ { maxResults: 50, startAt: 0 }).and_return(%w[sprint_1 sprint_2])
376
+
377
+ allow(sprint_controller)
378
+ .to receive(:fetch_jira_sprints).with(board,
379
+ { maxResults: 50, startAt: 50 }).and_return(%w[sprint_3 sprint_4])
380
+
381
+ allow(sprint_controller)
382
+ .to receive(:fetch_jira_sprints).with(board, { maxResults: 50, startAt: 100 }).and_return([])
383
+
384
+ expect(sprint_controller.unfiltered_jira_sprints(board)).to eq(%w[sprint_1 sprint_2 sprint_3 sprint_4])
385
+ end
386
+ end
387
+
388
+ describe "#fetch_jira_sprints" do
389
+ let(:jira_board) { jira_resource_double(JIRA::Resource::Board, sprints: []) }
390
+
391
+ before do
392
+ allow(board).to receive_messages(jira_board: jira_board)
393
+ end
394
+
395
+ it "gets the next batch of sprints" do
396
+ sprint_controller.fetch_jira_sprints(board, { maxResults: 512, startAt: 1024 })
397
+
398
+ expect(jira_board).to have_received(:sprints).with(maxResults: 512, startAt: 1024)
399
+ end
400
+ end
401
+ end
402
+ end
403
+
404
+ # rubocop:enable Metrics/ClassLength
405
+ end
406
+ end