ticket-replicator 0.1.1 → 1.1.0
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/.rubocop.yml +8 -0
- data/README.md +7 -8
- data/config/examples/ticket-replicator.mappings.yml +1 -28
- data/cucumber.yml +1 -1
- data/features/load_tickets_in_jira.feature +65 -69
- data/features/setup_ticket_replicator.feature +1 -28
- data/features/step_definitions/load_tickets_in_jira_steps.rb +1 -1
- data/features/transform-solution-manager-tickets-into-jira-loadable-tickets.feature +51 -104
- data/features/transform_and_load_extracted_ticket_queue.feature +23 -46
- data/lib/ticket/replicator/file_loader.rb +1 -1
- data/lib/ticket/replicator/jira_project.rb +4 -0
- data/lib/ticket/replicator/row_loader.rb +66 -3
- data/lib/ticket/replicator/row_transformer.rb +29 -6
- data/lib/ticket/replicator/ticket.rb +19 -0
- data/lib/ticket/replicator/version.rb +1 -1
- data/spec/ticket/replicator/file_loader_spec.rb +1 -1
- data/spec/ticket/replicator/file_replicator_spec.rb +0 -2
- data/spec/ticket/replicator/file_transformer_spec.rb +2 -1
- data/spec/ticket/replicator/jira_project_spec.rb +19 -0
- data/spec/ticket/replicator/row_loader_spec.rb +208 -15
- data/spec/ticket/replicator/row_transformer_spec.rb +72 -5
- data/spec/ticket/replicator/ticket_spec.rb +72 -2
- metadata +1 -1
@@ -20,12 +20,13 @@ module Ticket
|
|
20
20
|
end
|
21
21
|
|
22
22
|
describe ".fields_to_load" do
|
23
|
-
it { expect(described_class.fields_to_load).to eq(%i[id status resolution priority
|
23
|
+
it { expect(described_class.fields_to_load).to eq(%i[id status resolution priority summary source_ticket_url]) }
|
24
24
|
end
|
25
25
|
|
26
26
|
describe "#run" do
|
27
27
|
it do
|
28
28
|
expect(loader).to receive(:save_ticket)
|
29
|
+
expect(loader).to receive(:update_source_ticket_remote_link)
|
29
30
|
expect(loader).to receive(:transition_ticket_to_the_expected_status)
|
30
31
|
|
31
32
|
loader.run
|
@@ -56,6 +57,49 @@ module Ticket
|
|
56
57
|
end
|
57
58
|
end
|
58
59
|
|
60
|
+
describe "#jira_resolution_value" do
|
61
|
+
let(:loader) { described_class.send(:new, jira_project, row) }
|
62
|
+
let(:row) { { resolution: actual_resolution } }
|
63
|
+
let(:logger) { instance_double(Logger, info: nil) }
|
64
|
+
let(:resolutions) { { "Done" => double(id: "10004"), "Won't Fix" => double(id: "10005") } }
|
65
|
+
|
66
|
+
let(:jira_resolution_value) { loader.send(:jira_resolution_value) }
|
67
|
+
|
68
|
+
before do
|
69
|
+
allow(jira_project).to receive(:resolutions).and_return(resolutions)
|
70
|
+
allow(loader).to receive(:log).and_return(logger)
|
71
|
+
end
|
72
|
+
|
73
|
+
context "when the resolution is not set" do
|
74
|
+
let(:actual_resolution) { nil }
|
75
|
+
it { expect(jira_resolution_value).to be_nil }
|
76
|
+
end
|
77
|
+
|
78
|
+
context "when the resolution is an empty string" do
|
79
|
+
let(:actual_resolution) { "" }
|
80
|
+
it { expect(jira_resolution_value).to be_nil }
|
81
|
+
end
|
82
|
+
|
83
|
+
context "when the resolution is set to an existing value" do
|
84
|
+
let(:actual_resolution) { "Done" }
|
85
|
+
it { expect(jira_resolution_value).to eq({ name: "Done" }) }
|
86
|
+
end
|
87
|
+
|
88
|
+
context "when the resolution is set to an unknown value" do
|
89
|
+
let(:actual_resolution) { "an unknown resolution #{rand}" }
|
90
|
+
|
91
|
+
it do
|
92
|
+
expect(logger).to receive(:warn) do |&block|
|
93
|
+
expect(block.call)
|
94
|
+
.to eq("Setting resolution to unset " \
|
95
|
+
"since resolution #{actual_resolution.inspect} not found in #{resolutions.inspect}!")
|
96
|
+
end
|
97
|
+
|
98
|
+
expect(jira_resolution_value).to be_nil
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
59
103
|
describe "#fetch_ticket" do
|
60
104
|
let(:loader) { described_class.send(:new, jira_project, { id: "123" }) }
|
61
105
|
|
@@ -92,7 +136,8 @@ module Ticket
|
|
92
136
|
let(:loader) { described_class.send(:new, jira_project, row) }
|
93
137
|
|
94
138
|
let(:row) do
|
95
|
-
{ id: "123", priority: "Low", resolution: "", status: "Open", summary: "PREFIX | summary",
|
139
|
+
{ id: "123", priority: "Low", resolution: "Done", status: "Open", summary: "PREFIX | summary",
|
140
|
+
team: "A Team" }
|
96
141
|
end
|
97
142
|
|
98
143
|
let(:ticket) { instance_double(Ticket, jira_ticket: jira_ticket) }
|
@@ -100,8 +145,15 @@ module Ticket
|
|
100
145
|
let(:jira_ticket) { double(JIRA::Resource::Issue) }
|
101
146
|
|
102
147
|
before do
|
103
|
-
allow(loader).to receive_messages(
|
104
|
-
|
148
|
+
allow(loader).to receive_messages(
|
149
|
+
ticket: ticket,
|
150
|
+
:ticket_fields_need_to_be_updated? => ticket_fields_need_to_be_updated?
|
151
|
+
)
|
152
|
+
|
153
|
+
allow(jira_project)
|
154
|
+
.to receive_messages(resolutions: {
|
155
|
+
"Done" => nil, "Won't Do" => nil, "Duplicate" => nil, "Cannot Reproduce" => nil
|
156
|
+
})
|
105
157
|
end
|
106
158
|
|
107
159
|
context "when the previously replicated needs to be updated " do
|
@@ -112,9 +164,8 @@ module Ticket
|
|
112
164
|
fields: {
|
113
165
|
project: { key: "PROJKEY" },
|
114
166
|
issuetype: { name: "Bug" },
|
115
|
-
|
167
|
+
resolution: { name: "Done" },
|
116
168
|
priority: { name: "Low" },
|
117
|
-
# team: { name: "A Team" },
|
118
169
|
summary: "PREFIX | summary"
|
119
170
|
}
|
120
171
|
})
|
@@ -137,6 +188,30 @@ module Ticket
|
|
137
188
|
end
|
138
189
|
end
|
139
190
|
|
191
|
+
describe "#build_ticket_link_attributes" do
|
192
|
+
it "builds the link attributes with a default application" do
|
193
|
+
expect(described_class.send(:build_ticket_link_attributes,
|
194
|
+
"https://url/to/source/ticket/123", "Source Ticket 123"))
|
195
|
+
.to eq({ "object" => { "url" => "https://url/to/source/ticket/123", "title" => "Source Ticket 123" },
|
196
|
+
"application" => { "name" => "Ticket Source" } })
|
197
|
+
end
|
198
|
+
|
199
|
+
it "builds the link attributes with a custom application" do
|
200
|
+
expect(described_class.send(:build_ticket_link_attributes,
|
201
|
+
"https://url/to/source/ticket/123", "Source Ticket 123",
|
202
|
+
"A custom application"))
|
203
|
+
.to eq({ "object" => { "url" => "https://url/to/source/ticket/123", "title" => "Source Ticket 123" },
|
204
|
+
"application" => { "name" => "A custom application" } })
|
205
|
+
end
|
206
|
+
|
207
|
+
it "builds the link attributes with no application" do
|
208
|
+
expect(described_class.send(:build_ticket_link_attributes,
|
209
|
+
"https://url/to/source/ticket/123", "Source Ticket 123",
|
210
|
+
nil))
|
211
|
+
.to eq({ "object" => { "url" => "https://url/to/source/ticket/123", "title" => "Source Ticket 123" } })
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
140
215
|
describe "#ticket_fields_need_to_be_updated?" do
|
141
216
|
before do
|
142
217
|
allow(loader).to receive_messages(ticket_previously_replicated?: ticket_previously_replicated?,
|
@@ -225,21 +300,139 @@ module Ticket
|
|
225
300
|
end
|
226
301
|
end
|
227
302
|
|
228
|
-
|
303
|
+
# rubocop:disable Metrics/BlockLength
|
304
|
+
context "when caring for the source ticket link" do
|
305
|
+
def build_link(url, title, application_name = "Ticket Source")
|
306
|
+
RowLoader.build_ticket_link_attributes(url, title, application_name)
|
307
|
+
end
|
308
|
+
|
229
309
|
let(:loader) { described_class.send(:new, jira_project, row) }
|
230
|
-
let(:row) { { id: "123",
|
310
|
+
let(:row) { { id: "123", source_ticket_url: "https://url/to/source/ticket/123" } }
|
311
|
+
let(:ticket) { instance_double(Ticket, jira_ticket: jira_ticket) }
|
312
|
+
let(:jira_ticket) { double(JIRA::Resource::Issue, remotelink: double(build: remotelink)) }
|
313
|
+
let(:remotelink) { instance_double(JIRA::Resource::Remotelink) }
|
231
314
|
|
232
|
-
|
315
|
+
before { allow(loader).to receive_messages(ticket: ticket) }
|
233
316
|
|
234
|
-
|
235
|
-
|
236
|
-
|
317
|
+
let(:expected_link) { build_link("https://url/to/source/ticket/123", "Source Ticket 123") }
|
318
|
+
|
319
|
+
describe "#source_ticket_link_title" do
|
320
|
+
it { expect(loader.source_ticket_link_title).to eq("Source Ticket 123") }
|
321
|
+
end
|
322
|
+
|
323
|
+
describe "#update_source_ticket_remote_link" do
|
324
|
+
before do
|
325
|
+
allow(loader).to receive_messages(source_ticket_link_needs_update?: needs_update)
|
326
|
+
end
|
327
|
+
|
328
|
+
context "when the link does not exist" do
|
329
|
+
let(:needs_update) { true }
|
330
|
+
|
331
|
+
before { allow(ticket).to receive_messages(source_ticket_link: nil) }
|
332
|
+
|
333
|
+
it "setups the link" do
|
334
|
+
expect(remotelink).to receive(:save!).with(expected_link)
|
335
|
+
|
336
|
+
loader.update_source_ticket_remote_link
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
context "when the link needs to be updated" do
|
341
|
+
let(:needs_update) { true }
|
342
|
+
let(:source_ticket_link) { instance_double(JIRA::Resource::Remotelink) }
|
343
|
+
|
344
|
+
before { allow(ticket).to receive_messages(source_ticket_link: source_ticket_link) }
|
345
|
+
|
346
|
+
it "deletes the previous link and creates a new one" do
|
347
|
+
expect(source_ticket_link).to receive(:delete)
|
348
|
+
expect(remotelink).to receive(:save!).with(expected_link)
|
349
|
+
|
350
|
+
loader.update_source_ticket_remote_link
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
context "when the link does not need to be updated" do
|
355
|
+
let(:needs_update) { false }
|
356
|
+
|
357
|
+
it "no link creation happens" do
|
358
|
+
expect(remotelink).not_to receive(:save!)
|
359
|
+
|
360
|
+
loader.update_source_ticket_remote_link
|
361
|
+
end
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
describe "#source_ticket_link_needs_update?" do
|
366
|
+
before do
|
367
|
+
allow(ticket).to receive_messages(source_ticket_link: remote_link)
|
368
|
+
end
|
369
|
+
|
370
|
+
context "when link has yet to be created" do
|
371
|
+
let(:remote_link) { nil }
|
372
|
+
|
373
|
+
it { expect(loader.source_ticket_link_needs_update?).to be_truthy }
|
374
|
+
end
|
375
|
+
|
376
|
+
context "when link already exists" do
|
377
|
+
let(:remote_link) do
|
378
|
+
instance_double(JIRA::Resource::Remotelink,
|
379
|
+
attrs: source_ticket_link,
|
380
|
+
inspect: "<JIRA::Resource::Remotelink attrs: #{source_ticket_link}>")
|
381
|
+
end
|
382
|
+
|
383
|
+
context "when the link is not up to date" do
|
384
|
+
let(:source_ticket_link) { build_link(existing_url, existing_title) }
|
385
|
+
|
386
|
+
context "when url has changed" do
|
387
|
+
let(:existing_url) { "https://__OLD_URL__/to/source/ticket/1234" }
|
388
|
+
let(:existing_title) { "Source Ticket 123" }
|
389
|
+
|
390
|
+
it { expect(loader.source_ticket_link_needs_update?).to be_truthy }
|
391
|
+
end
|
392
|
+
|
393
|
+
context "when title has changed" do
|
394
|
+
let(:existing_url) { "https://url/to/source/ticket/123" }
|
395
|
+
let(:existing_title) { "__OLD TITLE__Source Ticket 1234" }
|
396
|
+
|
397
|
+
it { expect(loader.source_ticket_link_needs_update?).to be_truthy }
|
398
|
+
end
|
399
|
+
end
|
400
|
+
|
401
|
+
context "when the link is up to date" do
|
402
|
+
let(:existing_url) { "https://url/to/source/ticket/123" }
|
403
|
+
let(:existing_title) { "Source Ticket 123" }
|
404
|
+
let(:source_ticket_link) do
|
405
|
+
{ "object" => {
|
406
|
+
"url" => "https://url/to/source/ticket/123",
|
407
|
+
"title" => "Source Ticket 123",
|
408
|
+
"icon" => { "title" => "link", "url16x16" => "https://url/to/source/ticket/123/icon" }
|
409
|
+
},
|
410
|
+
"application" => { "name" => "Ticket Source" },
|
411
|
+
"extra_attributes" =>
|
412
|
+
{ "id" => 10_443, "self" => "https://url/to/source/ticket/123/remotelink/10443" } }
|
413
|
+
end
|
414
|
+
|
415
|
+
it("only checks the needed attributes") { expect(loader.source_ticket_link_needs_update?).to be_falsey }
|
416
|
+
end
|
417
|
+
end
|
418
|
+
end
|
419
|
+
# rubocop:enable Metrics/BlockLength
|
420
|
+
|
421
|
+
describe "#transition_ticket_to_the_expected_status" do
|
422
|
+
let(:loader) { described_class.send(:new, jira_project, row) }
|
423
|
+
let(:row) { { id: "123", status: "Testing" } }
|
424
|
+
|
425
|
+
let(:ticket) { double(Ticket) }
|
237
426
|
|
238
|
-
|
427
|
+
it do
|
428
|
+
expect(loader).to receive(:ticket).at_least(:once).and_return(ticket)
|
429
|
+
expect(ticket).to receive(:transition_to).with("Testing")
|
430
|
+
|
431
|
+
loader.transition_ticket_to_the_expected_status
|
432
|
+
end
|
239
433
|
end
|
240
434
|
end
|
241
435
|
end
|
436
|
+
# rubocop:enable Metrics/ClassLength
|
242
437
|
end
|
243
|
-
|
244
|
-
# rubocop:enable Metrics/ClassLength
|
245
438
|
end
|
@@ -33,11 +33,11 @@ RSpec.describe Ticket::Replicator::RowTransformer do
|
|
33
33
|
allow(transformer).to receive(:transformed_status).and_return("Open")
|
34
34
|
allow(transformer).to receive(:transformed_resolution).and_return("")
|
35
35
|
allow(transformer).to receive(:transformed_priority).and_return("Low")
|
36
|
-
allow(transformer).to receive(:transformed_team).and_return("Transformed Team")
|
37
36
|
allow(transformer).to receive(:transformed_summary).and_return("transformed summary (123)")
|
37
|
+
allow(transformer).to receive(:transformed_source_ticket_url).and_return("url/to/source/ticket/123")
|
38
38
|
|
39
39
|
expect(transformer.run)
|
40
|
-
.to eq(["123", "Open", "", "Low", "
|
40
|
+
.to eq(["123", "Open", "", "Low", "transformed summary (123)", "url/to/source/ticket/123"])
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
@@ -84,6 +84,46 @@ RSpec.describe Ticket::Replicator::RowTransformer do
|
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
87
|
+
describe "#ticket_replicator_source_ticket_url" do
|
88
|
+
let(:extracted_row) { {} }
|
89
|
+
|
90
|
+
context "when the source ticket url is set in the environment" do
|
91
|
+
before do
|
92
|
+
allow(ENV)
|
93
|
+
.to receive(:fetch).with("TICKET_REPLICATOR_SOURCE_TICKET_URL").and_return("url/to/source/ticket")
|
94
|
+
end
|
95
|
+
|
96
|
+
it { expect(transformer.ticket_replicator_source_ticket_url).to eq("url/to/source/ticket") }
|
97
|
+
end
|
98
|
+
|
99
|
+
context "when the source ticket url is not set in the environment" do
|
100
|
+
it do
|
101
|
+
expect { transformer.ticket_replicator_source_ticket_url }
|
102
|
+
.to raise_error("TICKET_REPLICATOR_SOURCE_TICKET_URL: not set in environment!")
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe "#source_ticket_url_builder" do
|
108
|
+
let(:extracted_row) { {} }
|
109
|
+
|
110
|
+
before do
|
111
|
+
allow(transformer).to receive_messages(ticket_replicator_source_ticket_url: ticket_replicator_source_ticket_url)
|
112
|
+
end
|
113
|
+
|
114
|
+
context "when the URL has no syntax error" do
|
115
|
+
let(:ticket_replicator_source_ticket_url) { "http://url/to/source/ticket/<%= source_ticket_id %>" }
|
116
|
+
|
117
|
+
it { expect(transformer.source_ticket_url_builder("123")).to eq("http://url/to/source/ticket/123") }
|
118
|
+
end
|
119
|
+
|
120
|
+
context "when the URL has a syntax error" do
|
121
|
+
let(:ticket_replicator_source_ticket_url) { "http://url/to/source/ticket/<%= missing_variable %>" }
|
122
|
+
|
123
|
+
it { expect { transformer.source_ticket_url_builder("123") }.to raise_error(StandardError) }
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
87
127
|
describe "using mappings" do
|
88
128
|
before { allow(transformer).to receive_messages(mappings: mappings) }
|
89
129
|
|
@@ -92,7 +132,7 @@ RSpec.describe Ticket::Replicator::RowTransformer do
|
|
92
132
|
{
|
93
133
|
"field_mapping" => {
|
94
134
|
"id" => "Defect", "priority" => "Defect Priority", "resolution" => "Defect (2)",
|
95
|
-
"status" => "Defect status", "summary" => "Defect (2)"
|
135
|
+
"status" => "Defect status", "summary" => "Defect (2)"
|
96
136
|
}
|
97
137
|
}
|
98
138
|
end
|
@@ -107,7 +147,7 @@ RSpec.describe Ticket::Replicator::RowTransformer do
|
|
107
147
|
it do
|
108
148
|
expect(transformer.remapped_field_extracted_row)
|
109
149
|
.to eq({ "id" => "123", "priority" => "High", "resolution" => "a summary",
|
110
|
-
"status" => "Open", "summary" => "a summary"
|
150
|
+
"status" => "Open", "summary" => "a summary" })
|
111
151
|
end
|
112
152
|
end
|
113
153
|
|
@@ -126,6 +166,21 @@ RSpec.describe Ticket::Replicator::RowTransformer do
|
|
126
166
|
end
|
127
167
|
end
|
128
168
|
|
169
|
+
describe "#transformed_source_ticket_url" do
|
170
|
+
let(:remapped_field_extracted_row) { { "id" => "123" } }
|
171
|
+
let(:mappings) { {} }
|
172
|
+
|
173
|
+
before do
|
174
|
+
allow(transformer)
|
175
|
+
.to receive_messages(transformed_id: "123",
|
176
|
+
ticket_replicator_source_ticket_url: "url/to/source/ticket/<%= source_ticket_id %>")
|
177
|
+
end
|
178
|
+
|
179
|
+
it "returns the source ticket url" do
|
180
|
+
expect(transformer.transformed_source_ticket_url).to eq("url/to/source/ticket/123")
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
129
184
|
describe "#transformed_summary" do
|
130
185
|
let(:remapped_field_extracted_row) { { "id" => "426", "summary" => "a summary" } }
|
131
186
|
let(:mappings) { {} }
|
@@ -155,7 +210,19 @@ RSpec.describe Ticket::Replicator::RowTransformer do
|
|
155
210
|
it { expect(transformed_value).to eq(an_original_value) }
|
156
211
|
end
|
157
212
|
|
158
|
-
context "when
|
213
|
+
context "when defaulting to unset value" do
|
214
|
+
let(:mappings) { { "#{field_name}_mapping" => { "defaults_to" => "unset_value" } } }
|
215
|
+
|
216
|
+
it { expect(transformed_value).to eq(nil) }
|
217
|
+
end
|
218
|
+
|
219
|
+
context "when defaulting to blank value" do
|
220
|
+
let(:mappings) { { "#{field_name}_mapping" => { "defaults_to" => "blank_value" } } }
|
221
|
+
|
222
|
+
it { expect(transformed_value).to eq("") }
|
223
|
+
end
|
224
|
+
|
225
|
+
context "when the value is unexpected" do
|
159
226
|
let(:mappings) do
|
160
227
|
{ "#{field_name}_mapping" => { "extracted value" => "transformed value" } }
|
161
228
|
end
|
@@ -136,7 +136,6 @@ module Ticket
|
|
136
136
|
let(:jira_auto_tool) { instance_double(Jira::Auto::Tool) }
|
137
137
|
let(:jira_client) { instance_double(JIRA::Client, Field: field_navigator) }
|
138
138
|
|
139
|
-
# let(:jira_ticket) { OpenStruct.new(jira_ticket_properties_hash["fields"]) }
|
140
139
|
let(:jira_ticket) { JIRA::Resource::Issue.build(jira_client, jira_ticket_properties_hash) }
|
141
140
|
|
142
141
|
let(:ticket) { described_class.new(jira_auto_tool, jira_ticket) }
|
@@ -149,6 +148,56 @@ module Ticket
|
|
149
148
|
it { expect(ticket.summary).to eq("SMAN-16384 | Login page randomly fails to load CSS assets (10001)") }
|
150
149
|
end
|
151
150
|
|
151
|
+
def build_ticket_link(url, title, application = Ticket::SOURCE_TICKET_REMOTE_LINK_APPLICATION)
|
152
|
+
double(JIRA::Resource::Remotelink, attrs: RowLoader.build_ticket_link_attributes(url, title, application))
|
153
|
+
end
|
154
|
+
|
155
|
+
describe "#source_ticket_link" do
|
156
|
+
let(:ticket_links) { [double(JIRA::Resource::Remotelink, attrs: {}), source_ticket_jira_link].compact }
|
157
|
+
|
158
|
+
before { allow(jira_ticket).to receive_messages(remotelink: double(all: ticket_links)) }
|
159
|
+
|
160
|
+
let(:source_ticket_jira_link) { build_ticket_link("https://ur/to/source/ticket/16384", "Source Ticket 16384") }
|
161
|
+
|
162
|
+
it { expect(ticket.source_ticket_link).to eq(source_ticket_jira_link) }
|
163
|
+
|
164
|
+
context "when no source ticket is linked" do
|
165
|
+
let(:source_ticket_jira_link) { nil }
|
166
|
+
it { expect(ticket.source_ticket_link).to be_nil }
|
167
|
+
end
|
168
|
+
|
169
|
+
context "when the existing remote link is not a ticket source link (no application specified)" do
|
170
|
+
let(:source_ticket_jira_link) do
|
171
|
+
build_ticket_link("https://ur/to/source/ticket/16384", "Source Ticket 16384", nil)
|
172
|
+
end
|
173
|
+
|
174
|
+
it { expect(ticket.source_ticket_link).to be_nil }
|
175
|
+
end
|
176
|
+
|
177
|
+
context "when the existing remote link is not a ticket source link (another application specified)" do
|
178
|
+
let(:source_ticket_jira_link) do
|
179
|
+
build_ticket_link("https://ur/to/source/ticket/16384", "Source Ticket 16384", "Another application")
|
180
|
+
end
|
181
|
+
|
182
|
+
it { expect(ticket.source_ticket_link).to be_nil }
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
describe "#source_ticket_url" do
|
187
|
+
before do
|
188
|
+
allow(ticket).to receive_messages(source_ticket_link: source_ticket_jira_link)
|
189
|
+
end
|
190
|
+
|
191
|
+
let(:source_ticket_jira_link) { build_ticket_link("https://ur/to/source/ticket/16384", "Source Ticket 16384") }
|
192
|
+
|
193
|
+
it { expect(ticket.source_ticket_url).to eq("https://ur/to/source/ticket/16384") }
|
194
|
+
|
195
|
+
context "when no source ticket is linked" do
|
196
|
+
let(:source_ticket_jira_link) { nil }
|
197
|
+
it { expect(ticket.source_ticket_url).to be_nil }
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
152
201
|
describe "replicated?" do
|
153
202
|
let(:ticket) { described_class.new(jira_auto_tool, jira_ticket) }
|
154
203
|
let(:jira_ticket) { double(JIRA::Resource::Issue, summary: actual_summary) }
|
@@ -238,7 +287,28 @@ module Ticket
|
|
238
287
|
ticket.transition_to("Testing")
|
239
288
|
end
|
240
289
|
end
|
290
|
+
|
291
|
+
describe "#sanitize" do
|
292
|
+
let(:expectations) do
|
293
|
+
[
|
294
|
+
["value as name attribute", double(name: "value as name attribute")],
|
295
|
+
["value as value attribute", double(value: "value as value attribute")],
|
296
|
+
["value from name entry in hash", { "name" => "value from name entry in hash" }],
|
297
|
+
["value from value entry in hash", { "value" => "value from value entry in hash" }],
|
298
|
+
["value as a string", "value as a string"],
|
299
|
+
["125", 125],
|
300
|
+
["object as a string", double(to_s: "object as a string")],
|
301
|
+
["", nil]
|
302
|
+
]
|
303
|
+
end
|
304
|
+
|
305
|
+
it do
|
306
|
+
expectations.each do |expected_sanitized_value, value|
|
307
|
+
expect(ticket.send(:sanitize, value)).to eq(expected_sanitized_value)
|
308
|
+
end
|
309
|
+
end
|
310
|
+
end
|
241
311
|
end
|
242
312
|
end
|
243
|
-
# rubocop:enable Metrics/ClassLength
|
244
313
|
end
|
314
|
+
# rubocop:enable Metrics/ClassLength
|