ticket-replicator 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 (64) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +20 -0
  4. data/CHANGELOG.md +5 -0
  5. data/CODE_OF_CONDUCT.md +132 -0
  6. data/Guardfile +158 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +136 -0
  9. data/Rakefile +23 -0
  10. data/bin/ticket-replicator +67 -0
  11. data/config/examples/ticket-replicator.mappings.yml +54 -0
  12. data/cucumber.yml +7 -0
  13. data/features/extract-sap-solution-manager-defect-tickets.feature +45 -0
  14. data/features/load_tickets_in_jira.feature +129 -0
  15. data/features/setup_ticket_replicator.feature +85 -0
  16. data/features/step_definitions/anonymized_sample.xlsx +0 -0
  17. data/features/step_definitions/anonymized_sample.xlsx:Zone.Identifier +3 -0
  18. data/features/step_definitions/execution_context_steps.rb +13 -0
  19. data/features/step_definitions/extract_defect_tickets_from_sap_solution_manager_steps.rb.rb +29 -0
  20. data/features/step_definitions/load_tickets_in_jira_steps.rb +47 -0
  21. data/features/step_definitions/transform_solution_manager_tickets_steps.rb +21 -0
  22. data/features/support/10.setup_cucumber.rb +10 -0
  23. data/features/support/env.rb +15 -0
  24. data/features/support/hooks.rb +13 -0
  25. data/features/support/manage_mock_sap_solution_manager.rb.DISABLED +12 -0
  26. data/features/support/mocks/mock_defect_ticket_server.rb.DISABLED +251 -0
  27. data/features/support/setup_rspec.rb +15 -0
  28. data/features/support/setup_simplecov.rb +5 -0
  29. data/features/transform-solution-manager-tickets-into-jira-loadable-tickets.feature +313 -0
  30. data/features/transform_and_load_extracted_ticket_queue.feature +121 -0
  31. data/lib/tasks/version.rake +55 -0
  32. data/lib/ticket/replicator/defect_export_automation.rb.DISABLED +128 -0
  33. data/lib/ticket/replicator/file_loader.rb +46 -0
  34. data/lib/ticket/replicator/file_replicator.rb +67 -0
  35. data/lib/ticket/replicator/file_transformer/for_csv.rb +22 -0
  36. data/lib/ticket/replicator/file_transformer/for_xlsx.rb +34 -0
  37. data/lib/ticket/replicator/file_transformer.rb +70 -0
  38. data/lib/ticket/replicator/jira_project.rb +65 -0
  39. data/lib/ticket/replicator/replicated_summary.rb +73 -0
  40. data/lib/ticket/replicator/row_loader.rb +109 -0
  41. data/lib/ticket/replicator/row_transformer.rb +126 -0
  42. data/lib/ticket/replicator/s_a_p_solution_manager_client.rb.DISABLED +169 -0
  43. data/lib/ticket/replicator/setup.rb +49 -0
  44. data/lib/ticket/replicator/ticket.rb +70 -0
  45. data/lib/ticket/replicator/ticket_status_transitioner.rb +45 -0
  46. data/lib/ticket/replicator/version.rb +7 -0
  47. data/lib/ticket/replicator.rb +90 -0
  48. data/sig/ticket/replicator.rbs +6 -0
  49. data/spec/spec_helper.rb +19 -0
  50. data/spec/ticket/replicator/file_loader_spec.rb +77 -0
  51. data/spec/ticket/replicator/file_replicator_spec.rb +153 -0
  52. data/spec/ticket/replicator/file_transformer/for_csv_spec.rb +52 -0
  53. data/spec/ticket/replicator/file_transformer/for_xlsx_spec.rb +52 -0
  54. data/spec/ticket/replicator/file_transformer_spec.rb +83 -0
  55. data/spec/ticket/replicator/jira_project_spec.rb +127 -0
  56. data/spec/ticket/replicator/replicated_summary_spec.rb +70 -0
  57. data/spec/ticket/replicator/row_loader_spec.rb +245 -0
  58. data/spec/ticket/replicator/row_transformer_spec.rb +234 -0
  59. data/spec/ticket/replicator/setup_spec.rb +80 -0
  60. data/spec/ticket/replicator/ticket_spec.rb +244 -0
  61. data/spec/ticket/replicator/ticket_status_transitioner_spec.rb +123 -0
  62. data/spec/ticket/replicator_spec.rb +137 -0
  63. data/transformed_file1 +1 -0
  64. metadata +235 -0
@@ -0,0 +1,45 @@
1
+ @in-specification
2
+ Feature: Extract defect tickets from SAP Solution Manager
3
+ As an integration system
4
+ I want to extract defect tickets from SAP
5
+ So that I can prepare them for transformation
6
+
7
+ Scenario: Successfully extract defect tickets
8
+ Given the SAP system contains the following defect tickets:
9
+ | ID | Status | Priority | Team | Summary |
10
+ | 10001 | New | 2-High | Frontend | Login page randomly fails to load CSS assets |
11
+ | 10002 | In Progress | 1-Critical | Backend | Database deadlock during order processing |
12
+ | 10003 | Resolved | 3-Medium | Integration | Invalid date format in SOAP response |
13
+ | 10004 | Closed | 4-Low | Mobile | App crashes when offline on Android 12 |
14
+ | 10005 | Open | 2-High | Security | Session tokens not properly invalidated |
15
+ | 10006 | In Review | 3-Medium | DevOps | Jenkins pipeline timeout on large builds |
16
+ | 10007 | Rejected | 4-Low | QA | Test data missing edge case scenarios |
17
+ | 10008 | Confirmed | 1-Critical | Architecture | Memory leak in caching implementation |
18
+ | 10009 | On Hold | 3-Medium | UX | Inconsistent button styles across modules |
19
+ | 10010 | Fixed | 2-High | Performance | Slow response time on product search API |
20
+ When I run the extract process
21
+ Given the SAP system contains defect tickets
22
+ When I run the extract process
23
+ Then a file named "sap_defects.csv" should exist
24
+ And the file "sap_defects.csv" should contain exactly:
25
+ """
26
+ "ID","Status","Priority","Team","Summary"
27
+ "10001","New","2-High","Frontend","Login page randomly fails to load CSS assets (10001)"
28
+ "10002","In Progress","1-Critical","Backend","Database deadlock during order processing (10002)"
29
+ "10003","Resolved","3-Medium","Integration","Invalid date format in SOAP response (10003)"
30
+ "10004","Closed","4-Low","Mobile","App crashes when offline on Android 12 (10004)"
31
+ "10005","Open","2-High","Security","Session tokens not properly invalidated (10005)"
32
+ "10006","In Review","3-Medium","DevOps","Jenkins pipeline timeout on large builds (10006)"
33
+ "10007","Rejected","4-Low","QA","Test data missing edge case scenarios (10007)"
34
+ "10008","Confirmed","1-Critical","Architecture","Memory leak in caching implementation (10008)"
35
+ "10009","On Hold","3-Medium","UX","Inconsistent button styles across modules (10009)"
36
+ "10010","Fixed","2-High","Performance","Slow response time on product search API (10010)"
37
+ """
38
+
39
+
40
+
41
+ Scenario: Handle SAP connection error
42
+ Given the SAP system is unavailable
43
+ When I run the extract process
44
+ Then the process should fail gracefully
45
+ And an error should be logged
@@ -0,0 +1,129 @@
1
+ Feature: Load tickets into Jira
2
+ In order to achieve overall transparency in a single ticket system
3
+ As team
4
+ I want to load the SAP tickets in Jira
5
+
6
+ Background:
7
+ Given the following environment variables have already been set with a value:
8
+ | name |
9
+ | TICKET_REPLICATOR_JIRA_PROJECT_KEY |
10
+ | TICKET_REPLICATOR_JIRA_TICKET_TYPE_NAME |
11
+ And the project has no tickets
12
+
13
+ Scenario: Load tickets in Jira
14
+ Given a file named "queue/20.transformed/sap_solution_manager_defects.csv" with:
15
+ """
16
+ "ID","Status","Resolution","Priority","Team","Summary"
17
+ "10001","Open","","Highest","A16 Restaurant","SMAN-10001 | Login page randomly fails to load CSS assets (10001)"
18
+ "10002","In Process","","Highest","A16 Platform","SMAN-10002 | Database deadlock during order processing (10002)"
19
+ "10003","Confirmed","Fixed","Medium","A16 Logistic","SMAN-10003 | Invalid date format in SOAP response (10003)"
20
+ "10004","Closed","Done","Low","A16 Market","SMAN-10004 | App crashes when offline on Android 12 (10004)"
21
+ "10005","Open","","High","A16 CRM","SMAN-10005 | Session tokens not properly invalidated (10005)"
22
+ "10006","Solution Proposal","","Medium","A16 Supply","SMAN-10006 | Jenkins pipeline timeout on large builds (10006)"
23
+ "10007","Withdrawn","Won't Do","Low","A16 E2E-Test","SMAN-10007 | Test data missing edge case scenarios (10007)"
24
+ "10008","Open","","Highest","A16 Markets","SMAN-10008 | Memory leak in caching implementation (10008)"
25
+ "10009","Wait on External","","Medium","A16 Platform","SMAN-10009 | Inconsistent button styles across modules (10009)"
26
+ """
27
+ When I successfully run `ticket-replicator --load`
28
+ Then the Jira project should only have the following tickets:
29
+ | status | resolution | priority | team | summary | source ticket url |
30
+ | Open | | Highest | A16 Restaurant | SMAN-10001 \| Login page randomly fails to load CSS assets (10001) | https://sap.example/id/10001 |
31
+ | In Process | | Highest | A16 Platform | SMAN-10002 \| Database deadlock during order processing (10002) | https://sap.example/id/10002 |
32
+ | Confirmed | Fixed | Medium | A16 Logistic | SMAN-10003 \| Invalid date format in SOAP response (10003) | https://sap.example/id/10003 |
33
+ | Closed | Done | Low | A16 Market | SMAN-10004 \| App crashes when offline on Android 12 (10004) | https://sap.example/id/10004 |
34
+ | Open | | High | A16 CRM | SMAN-10005 \| Session tokens not properly invalidated (10005) | https://sap.example/id/10005 |
35
+ | Solution Proposal | | Medium | A16 Supply | SMAN-10006 \| Jenkins pipeline timeout on large builds (10006) | https://sap.example/id/10006 |
36
+ | Withdrawn | Won't Do | Low | A16 E2E-Test | SMAN-10007 \| Test data missing edge case scenarios (10007) | https://sap.example/id/10007 |
37
+ | Open | | Highest | A16 Markets | SMAN-10008 \| Memory leak in caching implementation (10008) | https://sap.example/id/10008 |
38
+ | Wait on External | | Medium | A16 Platform | SMAN-10009 \| Inconsistent button styles across modules (10009) | https://sap.example/id/10009 |
39
+ And the source ticket URL is found in the ticket descriptions of those tickets
40
+
41
+ Scenario: Loading the ticket information twice in Jira does not create additional tickets
42
+ Given a file named "queue/20.transformed/sap_solution_manager_defects.csv" with:
43
+ """
44
+ "ID","Status","Resolution","Priority","Team","Summary"
45
+ "10001","Open","","Highest","A16 Restaurant","SMAN-10001 | Login page randomly fails to load CSS assets (10001)"
46
+ "10002","In Process","","Highest","A16 Platform","SMAN-10002 | Database deadlock during order processing (10002)"
47
+ """
48
+ And a file named "queue/20.transformed/sap_solution_manager_defects.SAME_CONTENT.csv" with:
49
+ """
50
+ "ID","Status","Resolution","Priority","Team","Summary"
51
+ "10001","Open","","Highest","A16 Restaurant","SMAN-10001 | Login page randomly fails to load CSS assets (10001)"
52
+ "10002","In Process","","Highest","A16 Platform","SMAN-10002 | Database deadlock during order processing (10002)"
53
+ """
54
+ When I successfully run `ticket-replicator --load`
55
+ Then the Jira project should only have the following tickets:
56
+ | status | resolution | priority | team | summary | source ticket url |
57
+ | Open | | Highest | A16 Restaurant | SMAN-10001 \| Login page randomly fails to load CSS assets (10001) | https://sap.example/id/10001 |
58
+ | In Process | | Highest | A16 Platform | SMAN-10002 \| Database deadlock during order processing (10002) | https://sap.example/id/10002 |
59
+ And the source ticket URL is found in the ticket descriptions of those tickets
60
+
61
+ Scenario: Tickets are updated only if changes happened or they were not replicated before
62
+ Given a file named "queue/20.transformed/2025-03-29.16h16.sap_solution_manager_defects.csv" with:
63
+ """
64
+ "ID","Status","Resolution","Priority","Team","Summary"
65
+ "10001","Open","","Highest","A16 Restaurant","SMAN-10001 | Login page randomly fails to load CSS assets (10001)"
66
+ "10002","In Process","","Medium","A16 Platform","SMAN-10002 | Database deadlock during order processing (10002)"
67
+ "10016","Confirmed","Fixed","High","Performance Team","SMAN-10016 | Slow response time on product search API (10016)"
68
+ """
69
+ And I successfully run `ticket-replicator --load`
70
+ When a file named "queue/20.transformed/2025-03-29.19h56.update_tickets.csv" with:
71
+ """
72
+ "ID","Status","Resolution","Priority","Team","Summary"
73
+ "10001","Closed","","Highest","A16 Restaurant","SMAN-10001 | Login page randomly fails to load CSS assets (10001)"
74
+ "10002","In Process","","High","A16 Platform","SMAN-10002 | *Recurring* database deadlock during order processing (10002)"
75
+ "10008","Open","","Highest","A16 Markets","SMAN-10008 | Memory leak in caching implementation (10008)"
76
+ "10016","Confirmed","Fixed","High","Performance Team","SMAN-10016 | Slow response time on product search API (10016)"
77
+ """
78
+ And I successfully run `ticket-replicator --jira-http-debug --load`
79
+ Then the Jira project should only have the following tickets:
80
+ | example purpose | status | resolution | priority | team | summary | source ticket url |
81
+ | one update due to status change | Closed | | Highest | A16 Restaurant | SMAN-10001 \| Login page randomly fails to load CSS assets (10001) | https://sap.example/id/10001 |
82
+ | one update due to priority and summary updates | In Process | | High | A16 Platform | SMAN-10002 \| *Recurring* database deadlock during order processing (10002) | https://sap.example/id/10002 |
83
+ | two updates due to new ticket created (fields and status changes) | Open | | Highest | A16 Markets | SMAN-10008 \| Memory leak in caching implementation (10008) | https://sap.example/id/10008 |
84
+ | no update since no status or field change | Confirmed | Fixed | High | Performance Team | SMAN-10016 \| Slow response time on product search API (10016) | https://sap.example/id/10016 |
85
+ And only 4 Jira update requests were emitted
86
+
87
+ Scenario: Attempting to set an unexpected status generates information about the current row being loaded
88
+ Given a file named "queue/20.transformed/sap_solution_manager_defects.csv" with:
89
+ """
90
+ "ID","Status","Resolution","Priority","Team","Summary"
91
+ "10001","Open","","Highest","A16 Restaurant","SMAN-10001 | Login page randomly fails to load CSS assets (10001)"
92
+ "10002","In Process","","Highest","A16 Platform","SMAN-10002 | Database deadlock during order processing (10002)"
93
+ "10003","Confirmed","Fixed","Medium","A16 Logistic","SMAN-10003 | Invalid date format in SOAP response (10003)"
94
+ "10004","____ INEXISTING STATUS ____","Done","Low","A16 Market","SMAN-10004 | App crashes when offline on Android 12 (10004)"
95
+ "10005","Open","","High","A16 CRM","SMAN-10005 | Session tokens not properly invalidated (10005)"
96
+ "10006","Solution Proposal","","Medium","A16 Supply","SMAN-10006 | Jenkins pipeline timeout on large builds (10006)"
97
+ "10007","Withdrawn","Won't Do","Low","A16 E2E-Test","SMAN-10007 | Test data missing edge case scenarios (10007)"
98
+ "10008","Open","","Highest","A16 Markets","SMAN-10008 | Memory leak in caching implementation (10008)"
99
+ "10009","Wait on External","","Medium","A16 Platform","SMAN-10009 | Inconsistent button styles across modules (10009)"
100
+ """
101
+ When I run `ticket-replicator --load`
102
+ Then it should fail with:
103
+ """
104
+ ERROR Object : Ticket::Replicator::FileLoader::LoadError: queue/20.transformed/sap_solution_manager_defects.csv:5: error while loading row:
105
+ No transition found for "____ INEXISTING STATUS ____" in ["No Error -> No Error", "Tester Action -> Tester Action", "Close Bug -> Closed", "Confirmed -> Confirmed", "Defect Correction in Process -> Defect Correction in Process", "Deferred -> Deferred", "Forwarded -> Forwarded", "Information Required -> Information Required", "New -> New", "Open -> Open", "Solution Proposal -> Solution Proposal", "Wait for Defect Correction -> Wait for Defect Correction", "Wait on External -> Wait on External", "Withdrawn -> Withdrawn", "In Process -> In Process"].:
106
+ #<CSV::Row id:"10004" status:"____ INEXISTING STATUS ____" resolution:"Done" priority:"Low" team:"A16 Market" summary:"SMAN-10004 | App crashes when offline on Android 12 (10004)">
107
+ """
108
+
109
+ Scenario: Attempting to set an unexpected priority generates information about the current row being loaded
110
+ Given a file named "queue/20.transformed/sap_solution_manager_defects.csv" with:
111
+ """
112
+ "ID","Status","Resolution","Priority","Team","Summary"
113
+ "10001","Open","","Highest","A16 Restaurant","SMAN-10001 | Login page randomly fails to load CSS assets (10001)"
114
+ "10002","In Process","","Highest","A16 Platform","SMAN-10002 | Database deadlock during order processing (10002)"
115
+ "10003","Confirmed","Fixed","Medium","A16 Logistic","SMAN-10003 | Invalid date format in SOAP response (10003)"
116
+ "10004","Closed","Done","Low","A16 Market","SMAN-10004 | App crashes when offline on Android 12 (10004)"
117
+ "10005","Open","","High","A16 CRM","SMAN-10005 | Session tokens not properly invalidated (10005)"
118
+ "10006","Solution Proposal","","Medium","A16 Supply","SMAN-10006 | Jenkins pipeline timeout on large builds (10006)"
119
+ "10007","Withdrawn","Won't Do","Low","A16 E2E-Test","SMAN-10007 | Test data missing edge case scenarios (10007)"
120
+ "10008","Open","","____ UNEXPECTED PRIORITY ____","A16 Markets","SMAN-10008 | Memory leak in caching implementation (10008)"
121
+ "10009","Wait on External","","Medium","A16 Platform","SMAN-10009 | Inconsistent button styles across modules (10009)"
122
+ """
123
+ When I run `ticket-replicator --load`
124
+ Then it should fail with:
125
+ """
126
+ ERROR Object : Ticket::Replicator::FileLoader::LoadError: queue/20.transformed/sap_solution_manager_defects.csv:9: error while loading row:
127
+ Bad Request:
128
+ #<CSV::Row id:"10008" status:"Open" resolution:"" priority:"____ UNEXPECTED PRIORITY ____" team:"A16 Markets" summary:"SMAN-10008 | Memory leak in caching implementation (10008)">
129
+ """
@@ -0,0 +1,85 @@
1
+ @wip
2
+ Feature: Setup Ticket Replicator
3
+ In order to simplify the initial setup
4
+ As a user of ticket-replicator
5
+ I want to be able to setup the queue and generate an initial configuration
6
+
7
+ Scenario: Creating the environment configuration file
8
+ Given a file named "config/ticket-replicator.mappings.yml" does not exist
9
+ When I successfully run `ticket-replicator --setup`
10
+ Then the output should contain:
11
+ """
12
+ INFO Ticket::Replicator::Setup : Created folder "queue/10.extracted"
13
+ INFO Ticket::Replicator::Setup : Created file "config/ticket-replicator.mappings.yml"
14
+ """
15
+ And a file named "config/ticket-replicator.mappings.yml" should contain exactly:
16
+ """
17
+ ---
18
+ ### WARNING
19
+ ### WARNING - Example config: Please adapt to your context
20
+ ### WARNING
21
+ field_mapping:
22
+ id: Defect
23
+ summary: Defect (2)
24
+ priority: Defect Priority
25
+ resolution: Defect Status
26
+ status: Defect Status
27
+ team: Defect Support Team (2)
28
+
29
+ priority_mapping:
30
+ "1: Critical": "Highest"
31
+ "2: High": "High"
32
+ "3: Medium": "Medium"
33
+ "4: Low": "Low"
34
+
35
+ status_mapping:
36
+ defaults_to: keep_original_value
37
+
38
+ resolution_mapping:
39
+ defaults_to: keep_original_value
40
+ "New":
41
+ "Open":
42
+ "In Process":
43
+ "In Review":
44
+ "On Hold":
45
+ Deferred:
46
+ Defect Correction in Process:
47
+ "Fixed": "Fixed"
48
+ "Closed": "Done"
49
+ "Rejected": "Won't Do"
50
+ "Resolved": "Fixed"
51
+ "Confirmed":
52
+ "Forwarded":
53
+ "Information Required":
54
+ Wait for Defect Correction:
55
+ Solution Proposal:
56
+ Tester Action:
57
+ Wait on External:
58
+
59
+ team_mapping:
60
+ defaults_to: keep_original_value
61
+ "Frontend": "Web Team"
62
+ "Backend": "Server Team"
63
+ "Integration": "Integration Team"
64
+ "Mobile": "Mobile Team"
65
+ "Security": "Security Team"
66
+ "DevOps": "DevOps Team"
67
+ "QA": "Quality Assurance"
68
+ "Architecture": "Architecture Team"
69
+ "UX": "Design Team"
70
+ "Performance": "Performance Team"
71
+ """
72
+ And a directory named "queue/10.extracted" should exist
73
+
74
+ Scenario: Not overriding an existing environment configuration file
75
+ Given a file named "config/ticket-replicator.mappings.yml" with:
76
+ """
77
+ ---
78
+ # existing configuration
79
+ """
80
+ When I run `ticket-replicator --setup`
81
+ Then it should fail with:
82
+ """
83
+ INFO Ticket::Replicator::Setup : Created folder "queue/10.extracted"
84
+ ERROR Object : Ticket::Replicator::Setup::SetupError: Not overwriting existing config file "config/ticket-replicator.mappings.yml"
85
+ """
@@ -0,0 +1,3 @@
1
+ [ZoneTransfer]
2
+ ZoneId=3
3
+ HostUrl=about:internet
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ Given(/^the following environment variables have been set:$/) do |table|
4
+ table.hashes.each do |env_var|
5
+ name = env_var.fetch("name")
6
+ value = env_var.fetch("value")
7
+ set_environment_variable(name, value)
8
+ end
9
+ end
10
+
11
+ Given("the current date time is {string}") do |current_date_time|
12
+ set_environment_variable("JAT_CURRENT_DATE_TIME", current_date_time)
13
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ Given(/^the SAP system contains the following defect tickets:$/) do |table|
4
+ MockDefectTicketServer.set_tickets(table.hashes)
5
+ end
6
+
7
+ When(/^I run the extract process$/) do
8
+ @extractor = DefectTicketExtractor.new
9
+ @extractor.run
10
+ end
11
+
12
+ Given(/^the SAP system contains defect tickets$/) do
13
+ default_tickets = [
14
+ { ID: "DEF001", Status: "Open", Priority: "High", Team: "Core", Summary: "Test defect" }
15
+ ]
16
+ MockDefectTicketServer.set_tickets(default_tickets)
17
+ end
18
+
19
+ Given(/^the SAP system is unavailable$/) do
20
+ MockDefectTicketServer.simulate_unavailable
21
+ end
22
+
23
+ Then(/^the process should fail gracefully$/) do
24
+ expect { @extractor.run }.to raise_error(SAPConnectionError)
25
+ end
26
+
27
+ And(/^an error should be logged$/) do
28
+ expect(Logger).to have_received(:error).with(/SAP system unavailable/)
29
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ticket/replicator"
4
+
5
+ Given(/^the following environment variables have already been set with a value:$/) do |table|
6
+ # table is a table.hashes.keys # => [:name]
7
+ table.hashes.each { |env_var| expect(ENV).to have_key(env_var["name"]) }
8
+ end
9
+
10
+ Given(/^the project has no tickets$/) do
11
+ ticket_replicator.jira_project.all_tickets.each(&:delete)
12
+ end
13
+
14
+ Then(/^the Jira project should only have the following tickets:$/) do |table|
15
+ keys = table.headers - ["example purpose", "source ticket url", "team", "resolution"]
16
+
17
+ expected_tickets = table.hashes.map { |ticket| keys.collect { |key| ticket[key] } }.sort
18
+
19
+ log.debug { "expected_tickets =\n#{expected_tickets.inspect}" }
20
+
21
+ actual_tickets = ticket_replicator.jira_project.all_tickets.collect do |ticket|
22
+ keys.collect { |field_name| ticket.send(field_name) }
23
+ end.sort
24
+
25
+ log.debug { "actual_tickets =\n#{actual_tickets.inspect}" }
26
+
27
+ expect(actual_tickets).to match_array(expected_tickets)
28
+ end
29
+
30
+ And(/^only (\d+) Jira update requests were emitted$/) do |expected_update_request_count|
31
+ command_output = last_command_started.stdout
32
+ actual_put_count = command_output.scan("put").count
33
+ actual_post_count = command_output.scan("post").count
34
+
35
+ actual_update_request_count = actual_post_count + actual_put_count
36
+
37
+ expect(actual_update_request_count)
38
+ .to eq(expected_update_request_count.to_i), <<~EOEM
39
+
40
+ expected_update_request_count = #{expected_update_request_count}
41
+ != actual_update_request_count = #{actual_update_request_count}
42
+ actual_put_count = #{actual_put_count}
43
+ actual_post_count = #{actual_post_count}
44
+
45
+ Actual command output:\n#{command_output}"
46
+ EOEM
47
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "axlsx"
4
+ require "fileutils"
5
+
6
+ Given("an Excel file named {string}") do |path|
7
+ @excel_file_path = path
8
+ end
9
+
10
+ And("it has a tab named {string} with the following rows:") do |tab_name, table|
11
+ package = Axlsx::Package.new
12
+
13
+ package.workbook.add_worksheet(name: tab_name) do |sheet|
14
+ sheet.add_row(table.hashes.first.keys, types: :string)
15
+
16
+ table.hashes.each { |row| sheet.add_row(row.values, types: :string) }
17
+ end
18
+
19
+ create_directory(File.dirname(@excel_file_path))
20
+ cd(".") { package.serialize(@excel_file_path) }
21
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "aruba/cucumber"
4
+
5
+ Aruba.configure do |config|
6
+ config.exit_timeout = 300 # seconds
7
+
8
+ config.activate_announcer_on_command_failure = %i[command stdout stderr]
9
+ config.log_level = :debug
10
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "aruba/cucumber"
4
+
5
+ module TicketReplicatorWorld
6
+ def log
7
+ @log ||= Logging.logger[self]
8
+ end
9
+
10
+ def ticket_replicator
11
+ @ticket_replicator ||= Ticket::Replicator.new
12
+ end
13
+ end
14
+
15
+ World(TicketReplicatorWorld)
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ def ensure_the_aruba_sandbox_is_active
4
+ setup_aruba
5
+ ENV["HOME"] = expand_path(".")
6
+ cd(".")
7
+
8
+ expect(Dir.home).to eq(expand_path("."))
9
+ end
10
+
11
+ Before do
12
+ ensure_the_aruba_sandbox_is_active
13
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "mocks/mock_defect_ticket_server"
4
+
5
+ Before do
6
+ @mock_defect_ticket_server = MockDefectTicketServer.new(port: 9001)
7
+ @mock_defect_ticket_server.start
8
+ end
9
+
10
+ After do
11
+ @mock_defect_ticket_server&.stop
12
+ end