ticket-replicator 1.0.0 → 1.2.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.
@@ -2,245 +2,340 @@
2
2
 
3
3
  require "ticket/replicator/row_transformer"
4
4
 
5
- RSpec.describe Ticket::Replicator::RowTransformer do
6
- let(:transformer) { described_class.send(:new, extracted_row) }
5
+ module Ticket
6
+ class Replicator
7
+ # rubocop:disable Metrics/ClassLength
8
+ class RowTransformer
9
+ RSpec.describe RowTransformer do
10
+ let(:transformer) { described_class.send(:new, extracted_row) }
7
11
 
8
- describe ".run_on" do
9
- let(:extracted_row) { :a_row_to_transform }
12
+ describe ".run_on" do
13
+ let(:extracted_row) { :a_row_to_transform }
10
14
 
11
- it "transforms the given file" do
12
- expect(described_class).to receive(:new).with(:a_row_to_transform).and_return(transformer)
15
+ it "transforms the given file" do
16
+ expect(described_class).to receive(:new).with(:a_row_to_transform).and_return(transformer)
13
17
 
14
- expect(transformer).to receive(:run)
18
+ expect(transformer).to receive(:run)
15
19
 
16
- described_class.run_on(:a_row_to_transform)
17
- end
18
- end
20
+ described_class.run_on(:a_row_to_transform)
21
+ end
22
+ end
19
23
 
20
- describe "#run" do
21
- let(:extracted_row) do
22
- {
23
- id: "123",
24
- status: "Open",
25
- priority: "4 - Low",
26
- team: "Source Team",
27
- summary: "summary"
28
- }
29
- end
24
+ describe "#run" do
25
+ let(:extracted_row) do
26
+ {
27
+ id: "123",
28
+ status: "Open",
29
+ priority: "4 - Low",
30
+ team: "Source Team",
31
+ summary: "summary"
32
+ }
33
+ end
30
34
 
31
- it "transforms a row" do
32
- allow(transformer).to receive(:transformed_id).and_return("123")
33
- allow(transformer).to receive(:transformed_status).and_return("Open")
34
- allow(transformer).to receive(:transformed_resolution).and_return("")
35
- allow(transformer).to receive(:transformed_priority).and_return("Low")
36
- allow(transformer).to receive(:transformed_team).and_return("Transformed Team")
37
- allow(transformer).to receive(:transformed_summary).and_return("transformed summary (123)")
35
+ it "transforms a row" do
36
+ allow(transformer).to receive(:transformed_id).and_return("123")
37
+ allow(transformer).to receive(:transformed_status).and_return("Open")
38
+ allow(transformer).to receive(:transformed_resolution).and_return("")
39
+ allow(transformer).to receive(:transformed_priority).and_return("Low")
40
+ allow(transformer).to receive(:transformed_summary).and_return("transformed summary (123)")
41
+ allow(transformer).to receive(:transformed_source_ticket_url).and_return("url/to/source/ticket/123")
38
42
 
39
- expect(transformer.run)
40
- .to eq(["123", "Open", "", "Low", "transformed summary (123)"])
41
- end
42
- end
43
+ expect(transformer.run)
44
+ .to eq(["123", "Open", "", "Low", "transformed summary (123)", "url/to/source/ticket/123"])
45
+ end
46
+ end
43
47
 
44
- describe "#mappings" do
45
- let(:mappings_yaml) do
46
- <<~YAML
47
- field_mapping:
48
- id: Defect
49
- summary: Defect (2)
50
- status_mapping:
51
- defaults_to: keep_original_value
52
- Open: Open
53
- Closed: Closed
54
- resolution_mapping:
55
- Closed: Done
56
- Rejected: Won't Fix
57
- team_mapping:
58
- Source Team: Transformed Team
59
- Front End: Web Team
60
- priority_mapping:
61
- 1 - Critical: Critical
62
- 2 - High: High
63
- 3 - Medium: Medium
64
- 4 - Low: Low
65
- YAML
66
- end
48
+ describe "#mappings" do
49
+ let(:mappings_yaml) do
50
+ <<~'YAML'
51
+ field_mapping:
52
+ id: Defect
53
+ summary: Defect (2)
54
+ id_extraction_regex: "\\((?<id>\\d+)\\)$"
55
+ status_mapping:
56
+ defaults_to: keep_original_value
57
+ Open: Open
58
+ Closed: Closed
59
+ resolution_mapping:
60
+ Closed: Done
61
+ Rejected: Won't Fix
62
+ team_mapping:
63
+ Source Team: Transformed Team
64
+ Front End: Web Team
65
+ priority_mapping:
66
+ 1 - Critical: Critical
67
+ 2 - High: High
68
+ 3 - Medium: Medium
69
+ 4 - Low: Low
70
+ YAML
71
+ end
67
72
 
68
- let(:extracted_row) { {} }
73
+ let(:extracted_row) { {} }
74
+
75
+ let(:file_io) { instance_double(IO) }
76
+
77
+ it "loads the mappings from the mappings.yml file" do
78
+ expect(IO).to receive(:open).with("config/ticket-replicator.mappings.yml",
79
+ "r:bom|utf-8").and_yield(mappings_yaml)
80
+
81
+ expect(transformer.mappings)
82
+ .to eq(
83
+ "field_mapping" => { "id" => "Defect", "summary" => "Defect (2)" },
84
+ "id_extraction_regex" => "\\((?<id>\\d+)\\)$",
85
+ "status_mapping" => { "defaults_to" => "keep_original_value", "Open" => "Open",
86
+ "Closed" => "Closed" },
87
+ "resolution_mapping" => { "Closed" => "Done", "Rejected" => "Won't Fix" },
88
+ "team_mapping" => { "Source Team" => "Transformed Team", "Front End" => "Web Team" },
89
+ "priority_mapping" =>
90
+ { "1 - Critical" => "Critical", "2 - High" => "High", "3 - Medium" => "Medium",
91
+ "4 - Low" => "Low" }
92
+ )
93
+ end
94
+ end
69
95
 
70
- let(:file_io) { instance_double(IO) }
96
+ describe "#ticket_replicator_source_ticket_url" do
97
+ let(:extracted_row) { {} }
71
98
 
72
- it "loads the mappings from the mappings.yml file" do
73
- expect(IO).to receive(:open).with("config/ticket-replicator.mappings.yml", "r:bom|utf-8").and_yield(mappings_yaml)
99
+ context "when the source ticket url is set in the environment" do
100
+ before do
101
+ allow(ENV)
102
+ .to receive(:fetch).with("TICKET_REPLICATOR_SOURCE_TICKET_URL").and_return("url/to/source/ticket")
103
+ end
74
104
 
75
- expect(transformer.mappings)
76
- .to eq(
77
- "field_mapping" => { "id" => "Defect", "summary" => "Defect (2)" },
78
- "status_mapping" => { "defaults_to" => "keep_original_value", "Open" => "Open", "Closed" => "Closed" },
79
- "resolution_mapping" => { "Closed" => "Done", "Rejected" => "Won't Fix" },
80
- "team_mapping" => { "Source Team" => "Transformed Team", "Front End" => "Web Team" },
81
- "priority_mapping" =>
82
- { "1 - Critical" => "Critical", "2 - High" => "High", "3 - Medium" => "Medium", "4 - Low" => "Low" }
83
- )
84
- end
85
- end
105
+ it { expect(transformer.ticket_replicator_source_ticket_url).to eq("url/to/source/ticket") }
106
+ end
86
107
 
87
- describe "using mappings" do
88
- before { allow(transformer).to receive_messages(mappings: mappings) }
89
-
90
- describe "#remapped_field_extracted_row" do
91
- let(:mappings) do
92
- {
93
- "field_mapping" => {
94
- "id" => "Defect", "priority" => "Defect Priority", "resolution" => "Defect (2)",
95
- "status" => "Defect status", "summary" => "Defect (2)"
96
- }
97
- }
98
- end
108
+ context "when the source ticket url is not set in the environment" do
109
+ it do
110
+ expect { transformer.ticket_replicator_source_ticket_url }
111
+ .to raise_error("TICKET_REPLICATOR_SOURCE_TICKET_URL: not set in environment!")
112
+ end
113
+ end
114
+ end
99
115
 
100
- let(:extracted_row) do
101
- {
102
- "defect (2)" => "a summary", "defect priority" => "High", "defect status" => "Open",
103
- "defect team (2)" => "system team", "defect" => "123"
104
- }
105
- end
116
+ describe "#source_ticket_url_builder" do
117
+ let(:extracted_row) { {} }
106
118
 
107
- it do
108
- expect(transformer.remapped_field_extracted_row)
109
- .to eq({ "id" => "123", "priority" => "High", "resolution" => "a summary",
110
- "status" => "Open", "summary" => "a summary" })
111
- end
112
- end
119
+ before do
120
+ allow(transformer)
121
+ .to receive_messages(ticket_replicator_source_ticket_url: ticket_replicator_source_ticket_url)
122
+ end
113
123
 
114
- # rubocop:disable Metrics/BlockLength
115
- context "when remapped field extracted row used" do
116
- let(:extracted_row) { { :extracted_row => "should not be used in this context but the remapped version" } }
124
+ context "when the URL has no syntax error" do
125
+ let(:ticket_replicator_source_ticket_url) { "http://url/to/source/ticket/<%= source_ticket_id %>" }
117
126
 
118
- before { allow(transformer).to receive_messages(remapped_field_extracted_row: remapped_field_extracted_row) }
127
+ it { expect(transformer.source_ticket_url_builder("123")).to eq("http://url/to/source/ticket/123") }
128
+ end
119
129
 
120
- describe "#transformed_id" do
121
- let(:remapped_field_extracted_row) { { "id" => "123" } }
122
- let(:mappings) { {} }
130
+ context "when the URL has a syntax error" do
131
+ let(:ticket_replicator_source_ticket_url) { "http://url/to/source/ticket/<%= missing_variable %>" }
123
132
 
124
- it "returns the ID" do
125
- expect(transformer.transformed_id).to eq("123")
133
+ it { expect { transformer.source_ticket_url_builder("123") }.to raise_error(StandardError) }
134
+ end
126
135
  end
127
- end
128
136
 
129
- describe "#transformed_summary" do
130
- let(:remapped_field_extracted_row) { { "id" => "426", "summary" => "a summary" } }
131
- let(:mappings) { {} }
137
+ describe "using mappings" do
138
+ before { allow(transformer).to receive_messages(mappings: mappings) }
139
+
140
+ describe "#remapped_field_extracted_row" do
141
+ let(:mappings) do
142
+ {
143
+ "field_mapping" => {
144
+ "id" => "Defect", "priority" => "Defect Priority", "resolution" => "Defect (2)",
145
+ "status" => "Defect status", "summary" => "Defect (2)"
146
+ }
147
+ }
148
+ end
149
+
150
+ let(:extracted_row) do
151
+ {
152
+ "defect (2)" => "a summary", "defect priority" => "High", "defect status" => "Open",
153
+ "defect team (2)" => "system team", "defect" => "123"
154
+ }
155
+ end
156
+
157
+ it do
158
+ expect(transformer.remapped_field_extracted_row)
159
+ .to eq({ "id" => "123", "priority" => "High", "resolution" => "a summary",
160
+ "status" => "Open", "summary" => "a summary" })
161
+ end
162
+ end
132
163
 
133
- before do
134
- allow(Ticket::Replicator::ReplicatedSummary)
135
- .to receive(:build).with("426", "a summary").and_return("replicated_summary")
136
- end
164
+ # rubocop:disable Metrics/BlockLength
165
+ context "when remapped field extracted row used" do
166
+ let(:extracted_row) { { :extracted_row => "should not be used in this context but the remapped version" } }
137
167
 
138
- it "returns the summary" do
139
- expect(transformer.transformed_summary).to eq("replicated_summary")
140
- end
141
- end
168
+ before do
169
+ allow(transformer).to receive_messages(remapped_field_extracted_row: remapped_field_extracted_row)
170
+ end
142
171
 
143
- shared_examples "an unmapped value handler" do |field_name, source_field|
144
- source_field ||= field_name
172
+ describe "#transformed_id" do
173
+ context "when using the ID value as is" do
174
+ let(:mappings) { {} }
175
+ let(:remapped_field_extracted_row) { { "id" => "123" } }
145
176
 
146
- let(:remapped_field_extracted_row) { { source_field.to_s => an_original_value } }
177
+ it "returns the ID" do
178
+ expect(transformer.transformed_id).to eq("123")
179
+ end
180
+ end
147
181
 
148
- let(:an_original_value) { "any #{field_name} #{rand}" }
182
+ context "when extracting the ID from the string" do
183
+ let(:remapped_field_extracted_row) { { "id" => "also (85)73 in summary (123456)" } }
184
+ let(:mappings) { { "id_extraction_regex" => "\\((?<id>\\d+)\\)$" } }
149
185
 
150
- let(:transformed_value) { transformer.send("transformed_#{field_name}") }
186
+ it { expect(transformer.transformed_id).to eq("123456") }
151
187
 
152
- context "when defaulting to original value" do
153
- let(:mappings) { { "#{field_name}_mapping" => { "defaults_to" => "keep_original_value" } } }
188
+ context "when the regex does not match" do
189
+ let(:remapped_field_extracted_row) { { "id" => "summary (non numeric)" } }
154
190
 
155
- it { expect(transformed_value).to eq(an_original_value) }
156
- end
191
+ it "raises an error" do
192
+ expect { transformer.transformed_id }
193
+ .to raise_error(FileTransformer::TransformError,
194
+ %(No match found for :id in "summary (non numeric)") +
195
+ " using /\\((?<id>\\d+)\\)$/")
196
+ end
197
+ end
198
+ end
199
+ end
157
200
 
158
- context "when defaulting to unset value" do
159
- let(:mappings) { { "#{field_name}_mapping" => { "defaults_to" => "unset_value" } } }
201
+ describe "#transformed_source_ticket_url" do
202
+ let(:remapped_field_extracted_row) { { "id" => "123" } }
203
+ let(:mappings) { {} }
160
204
 
161
- it { expect(transformed_value).to eq(nil) }
162
- end
205
+ before do
206
+ allow(transformer)
207
+ .to receive_messages(
208
+ transformed_id: "123",
209
+ ticket_replicator_source_ticket_url: "url/to/source/ticket/<%= source_ticket_id %>"
210
+ )
211
+ end
163
212
 
164
- context "when defaulting to blank value" do
165
- let(:mappings) { { "#{field_name}_mapping" => { "defaults_to" => "blank_value" } } }
213
+ it "returns the source ticket url" do
214
+ expect(transformer.transformed_source_ticket_url).to eq("url/to/source/ticket/123")
215
+ end
216
+ end
166
217
 
167
- it { expect(transformed_value).to eq("") }
168
- end
218
+ describe "#transformed_summary" do
219
+ let(:remapped_field_extracted_row) { { "id" => "426", "summary" => "a summary" } }
220
+ let(:mappings) { {} }
169
221
 
170
- context "when the value is unexpected" do
171
- let(:mappings) do
172
- { "#{field_name}_mapping" => { "extracted value" => "transformed value" } }
173
- end
222
+ before do
223
+ allow(ReplicatedSummary).to receive(:build).with("426", "a summary").and_return("replicated_summary")
224
+ end
174
225
 
175
- it do
176
- expect { transformed_value }
177
- .to raise_error(RuntimeError,
178
- "No mapping found for #{field_name.inspect} = #{an_original_value.inspect} " \
179
- "in #{mappings["#{field_name}_mapping"].inspect}")
180
- end
181
- end
182
- end
226
+ it "returns the summary" do
227
+ expect(transformer.transformed_summary).to eq("replicated_summary")
228
+ end
229
+ end
183
230
 
184
- describe "#transformed_status" do
185
- let(:mappings) do
186
- { "status_mapping" => { "Open" => "Open", "Closed" => "Closed" } }
187
- end
231
+ shared_examples "an unmapped value handler" do |field_name, source_field|
232
+ source_field ||= field_name
188
233
 
189
- let(:remapped_field_extracted_row) { { "status" => "Open" } }
234
+ let(:remapped_field_extracted_row) { { source_field.to_s => an_original_value } }
190
235
 
191
- it "returns the status" do
192
- expect(transformer.transformed_status).to eq("Open")
193
- end
236
+ let(:an_original_value) { "any #{field_name} #{rand}" }
194
237
 
195
- it_behaves_like "an unmapped value handler", :status
196
- end
238
+ let(:transformed_value) { transformer.send("transformed_#{field_name}") }
197
239
 
198
- describe "#transformed_resolution" do
199
- let(:mappings) { { "resolution_mapping" => { "Closed" => "Done", "Rejected" => "Won't Fix" } } }
240
+ context "when defaulting to original value" do
241
+ let(:mappings) { { "#{field_name}_mapping" => { "defaults_to" => "keep_original_value" } } }
200
242
 
201
- context "when the status is Closed" do
202
- let(:remapped_field_extracted_row) { { "status" => "Closed" } }
243
+ it { expect(transformed_value).to eq(an_original_value) }
244
+ end
203
245
 
204
- it "returns the resolution" do
205
- expect(transformer.transformed_resolution).to eq("Done")
206
- end
207
- end
246
+ context "when defaulting to unset value" do
247
+ let(:mappings) { { "#{field_name}_mapping" => { "defaults_to" => "unset_value" } } }
208
248
 
209
- context "when the status is Rejected" do
210
- let(:remapped_field_extracted_row) { { "status" => "Rejected" } }
249
+ it { expect(transformed_value).to eq(nil) }
250
+ end
211
251
 
212
- it "returns the resolution" do
213
- expect(transformer.transformed_resolution).to eq("Won't Fix")
214
- end
215
- end
252
+ context "when defaulting to blank value" do
253
+ let(:mappings) { { "#{field_name}_mapping" => { "defaults_to" => "blank_value" } } }
216
254
 
217
- it_behaves_like "an unmapped value handler", :resolution, :status
218
- end
255
+ it { expect(transformed_value).to eq("") }
256
+ end
219
257
 
220
- describe "#transformed_team" do
221
- let(:mappings) { { "team_mapping" => { "Source Team" => "Transformed Team", "Front End" => "Web Team" } } }
258
+ context "when the value is unexpected" do
259
+ let(:mappings) do
260
+ { "#{field_name}_mapping" => { "extracted value" => "transformed value" } }
261
+ end
222
262
 
223
- let(:remapped_field_extracted_row) { { "team" => "Source Team" } }
263
+ it do
264
+ expect { transformed_value }
265
+ .to raise_error(RuntimeError,
266
+ "No mapping found for #{field_name.inspect} = #{an_original_value.inspect} " \
267
+ "in #{mappings["#{field_name}_mapping"].inspect}")
268
+ end
269
+ end
270
+ end
224
271
 
225
- it "returns the team" do
226
- expect(transformer.transformed_team).to eq("Transformed Team")
227
- end
272
+ describe "#transformed_status" do
273
+ let(:mappings) do
274
+ { "status_mapping" => { "Open" => "Open", "Closed" => "Closed" } }
275
+ end
228
276
 
229
- it_behaves_like "an unmapped value handler", :team
230
- end
277
+ let(:remapped_field_extracted_row) { { "status" => "Open" } }
231
278
 
232
- describe "#transformed_priority" do
233
- let(:mappings) { { "priority_mapping" => { "1 - Critical" => "Critical", "2 - High" => "High" } } }
279
+ it "returns the status" do
280
+ expect(transformer.transformed_status).to eq("Open")
281
+ end
234
282
 
235
- let(:remapped_field_extracted_row) { { "priority" => "1 - Critical" } }
283
+ it_behaves_like "an unmapped value handler", :status
284
+ end
236
285
 
237
- it "returns the priority" do
238
- expect(transformer.transformed_priority).to eq("Critical")
239
- end
286
+ describe "#transformed_resolution" do
287
+ let(:mappings) { { "resolution_mapping" => { "Closed" => "Done", "Rejected" => "Won't Fix" } } }
288
+
289
+ context "when the status is Closed" do
290
+ let(:remapped_field_extracted_row) { { "status" => "Closed" } }
291
+
292
+ it "returns the resolution" do
293
+ expect(transformer.transformed_resolution).to eq("Done")
294
+ end
295
+ end
296
+
297
+ context "when the status is Rejected" do
298
+ let(:remapped_field_extracted_row) { { "status" => "Rejected" } }
299
+
300
+ it "returns the resolution" do
301
+ expect(transformer.transformed_resolution).to eq("Won't Fix")
302
+ end
303
+ end
304
+
305
+ it_behaves_like "an unmapped value handler", :resolution, :status
306
+ end
307
+
308
+ describe "#transformed_team" do
309
+ let(:mappings) do
310
+ { "team_mapping" => { "Source Team" => "Transformed Team", "Front End" => "Web Team" } }
311
+ end
312
+
313
+ let(:remapped_field_extracted_row) { { "team" => "Source Team" } }
240
314
 
241
- it_behaves_like "an unmapped value handler", :priority
315
+ it "returns the team" do
316
+ expect(transformer.transformed_team).to eq("Transformed Team")
317
+ end
318
+
319
+ it_behaves_like "an unmapped value handler", :team
320
+ end
321
+
322
+ describe "#transformed_priority" do
323
+ let(:mappings) { { "priority_mapping" => { "1 - Critical" => "Critical", "2 - High" => "High" } } }
324
+
325
+ let(:remapped_field_extracted_row) { { "priority" => "1 - Critical" } }
326
+
327
+ it "returns the priority" do
328
+ expect(transformer.transformed_priority).to eq("Critical")
329
+ end
330
+
331
+ it_behaves_like "an unmapped value handler", :priority
332
+ end
333
+ end
334
+ # rubocop:enable Metrics/BlockLength
335
+ end
242
336
  end
243
337
  end
244
- # rubocop:enable Metrics/BlockLength
338
+
339
+ # rubocop:enable Metrics/ClassLength
245
340
  end
246
341
  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) }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ticket-replicator
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christophe Broult
@@ -146,6 +146,7 @@ extra_rdoc_files: []
146
146
  files:
147
147
  - ".rspec"
148
148
  - ".rubocop.yml"
149
+ - ".ruby-version"
149
150
  - CHANGELOG.md
150
151
  - CODE_OF_CONDUCT.md
151
152
  - Guardfile