qa_server 7.2.1 → 7.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop_fixme.yml +3 -0
  3. data/.travis.yml +4 -5
  4. data/CHANGELOG.md +41 -0
  5. data/Rakefile +1 -1
  6. data/app/assets/stylesheets/qa_server/_check-status.scss +36 -0
  7. data/app/cache_processors/concerns/qa_server/cache_keys.rb +0 -5
  8. data/app/cache_processors/qa_server/cache_expiry_service.rb +13 -8
  9. data/app/cache_processors/qa_server/job_id_cache.rb +29 -0
  10. data/app/cache_processors/qa_server/performance_cache.rb +34 -34
  11. data/app/cache_processors/qa_server/performance_day_graph_cache.rb +27 -0
  12. data/app/cache_processors/qa_server/performance_month_graph_cache.rb +27 -0
  13. data/app/cache_processors/qa_server/performance_year_graph_cache.rb +27 -0
  14. data/app/cache_processors/qa_server/scenario_history_cache.rb +7 -7
  15. data/app/cache_processors/qa_server/scenario_history_graph_cache.rb +12 -17
  16. data/app/cache_processors/qa_server/scenario_run_cache.rb +8 -8
  17. data/app/cache_processors/qa_server/scenario_run_failures_cache.rb +7 -7
  18. data/app/cache_processors/qa_server/scenario_run_summary_cache.rb +7 -7
  19. data/app/controllers/concerns/qa_server/authority_validation_behavior.rb +49 -44
  20. data/app/controllers/qa_server/check_status_controller.rb +92 -22
  21. data/app/controllers/qa_server/fetch_controller.rb +36 -36
  22. data/app/controllers/qa_server/monitor_status_controller.rb +108 -108
  23. data/app/jobs/qa_server/history_graph_job.rb +28 -0
  24. data/app/jobs/qa_server/monitor_tests_job.rb +19 -39
  25. data/app/jobs/qa_server/performance_day_graph_job.rb +45 -0
  26. data/app/jobs/qa_server/performance_month_graph_job.rb +45 -0
  27. data/app/jobs/qa_server/performance_per_byte_job.rb +85 -0
  28. data/app/jobs/qa_server/performance_year_graph_job.rb +45 -0
  29. data/app/loggers/qa_server/scenario_logger.rb +74 -4
  30. data/app/models/concerns/qa_server/performance_history_data_keys.rb +8 -0
  31. data/app/models/qa_server/authority_scenario.rb +4 -4
  32. data/app/models/qa_server/authority_status.rb +2 -2
  33. data/app/models/qa_server/authority_status_failure.rb +1 -1
  34. data/app/models/qa_server/performance_history.rb +2 -2
  35. data/app/models/qa_server/scenario_run_history.rb +52 -52
  36. data/app/models/qa_server/scenario_run_registry.rb +2 -2
  37. data/app/models/qa_server/scenarios.rb +26 -26
  38. data/app/models/qa_server/search_scenario.rb +24 -13
  39. data/app/models/qa_server/term_scenario.rb +29 -29
  40. data/app/prepends/prepended_linked_data/find_term.rb +40 -40
  41. data/app/prepends/prepended_linked_data/search_query.rb +36 -36
  42. data/app/prepends/prepended_rdf/rdf_graph.rb +7 -7
  43. data/app/presenters/concerns/qa_server/monitor_status/performance_datatable_behavior.rb +32 -32
  44. data/app/presenters/concerns/qa_server/monitor_status/performance_graph_behavior.rb +64 -64
  45. data/app/presenters/qa_server/check_status_presenter.rb +63 -7
  46. data/app/presenters/qa_server/monitor_status/current_status_presenter.rb +9 -8
  47. data/app/services/concerns/qa_server/gruff_graph.rb +16 -16
  48. data/app/services/qa_server/authority_loader_service.rb +14 -14
  49. data/app/services/qa_server/authority_validator_service.rb +1 -0
  50. data/app/services/qa_server/database_migrator.rb +14 -14
  51. data/app/services/qa_server/history_graphing_service.rb +30 -30
  52. data/app/services/qa_server/performance_calculator_service.rb +80 -80
  53. data/app/services/qa_server/performance_datatable_service.rb +35 -35
  54. data/app/services/qa_server/performance_graph_data_service.rb +28 -28
  55. data/app/services/qa_server/performance_graphing_service.rb +58 -58
  56. data/app/services/qa_server/performance_per_byte_calculator_service.rb +88 -0
  57. data/app/services/qa_server/performance_per_byte_data_service.rb +41 -0
  58. data/app/services/qa_server/scenarios_loader_service.rb +1 -1
  59. data/app/services/qa_server/time_period_service.rb +21 -21
  60. data/app/validators/qa_server/scenario_validator.rb +99 -87
  61. data/app/validators/qa_server/search_scenario_validator.rb +67 -61
  62. data/app/validators/qa_server/term_scenario_validator.rb +20 -15
  63. data/app/views/qa_server/check_status/index.html.erb +120 -24
  64. data/app/views/qa_server/monitor_status/_test_summary.html.erb +1 -1
  65. data/config/i18n-tasks.yml +133 -0
  66. data/config/locales/qa_server.en.yml +16 -0
  67. data/lib/generators/qa_server/assets_generator.rb +4 -4
  68. data/lib/generators/qa_server/templates/config/authorities/linked_data/cerl_ld4l_cache.json +2 -2
  69. data/lib/generators/qa_server/templates/config/authorities/linked_data/getty_aat_ld4l_cache.json +62 -1
  70. data/lib/generators/qa_server/templates/config/authorities/linked_data/getty_tgn_ld4l_cache.json +45 -11
  71. data/lib/generators/qa_server/templates/config/authorities/linked_data/getty_ulan_ld4l_cache.json +104 -8
  72. data/lib/generators/qa_server/templates/config/authorities/linked_data/isni_ld4l_cache.json +90 -0
  73. data/lib/generators/qa_server/templates/config/authorities/linked_data/ligatus_ld4l_cache.json +133 -0
  74. data/lib/generators/qa_server/templates/config/authorities/linked_data/locnames_rwo2_ld4l_cache.json +248 -0
  75. data/lib/generators/qa_server/templates/config/authorities/linked_data/locnames_rwo3_ld4l_cache.json +248 -0
  76. data/lib/generators/qa_server/templates/config/authorities/linked_data/locnames_rwo_ld4l_cache.json +4 -4
  77. data/lib/generators/qa_server/templates/config/authorities/linked_data/locvocabs_ld4l_cache.json +117 -0
  78. data/lib/generators/qa_server/templates/config/authorities/linked_data/mesh_nlm_ld4l_cache.json +135 -3
  79. data/lib/generators/qa_server/templates/config/authorities/linked_data/oclcfast_direct.json +5 -0
  80. data/lib/generators/qa_server/templates/config/authorities/linked_data/oclcfast_ld4l_cache.json +2 -4
  81. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/agrovoc_direct_validation.yml +31 -0
  82. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/agrovoc_ld4l_cache_validation.yml +31 -0
  83. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/cerl_ld4l_cache_validation.yml +26 -14
  84. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/dbpedia_ld4l_cache_validation.yml +33 -0
  85. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/geonames_direct_validation.yml +35 -0
  86. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/geonames_ld4l_cache_validation.yml +55 -5
  87. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/getty_aat_ld4l_cache_validation.yml +253 -0
  88. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/getty_tgn_ld4l_cache_validation.yml +31 -1
  89. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/getty_ulan_ld4l_cache_validation.yml +38 -1
  90. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/isni_ld4l_cache_validation.yml +10 -0
  91. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/ligatus_ld4l_cache_validation.yml +36 -0
  92. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/locdemographics_ld4l_cache_validation.yml +69 -44
  93. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/locgenres_ld4l_cache_validation.yml +22 -0
  94. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/locnames_ld4l_cache_validation.yml +65 -0
  95. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/locnames_rwo2_ld4l_cache_validation.yml +78 -0
  96. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/locnames_rwo3_ld4l_cache_validation.yml +73 -0
  97. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/locnames_rwo_ld4l_cache_validation.yml +71 -3
  98. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/locperformance_ld4l_cache_validation.yml +6 -0
  99. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/locsubjects_ld4l_cache_validation.yml +30 -0
  100. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/locvocabs_ld4l_cache_validation.yml +430 -0
  101. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/mesh_nlm_ld4l_cache_validation.yml +54 -1
  102. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/nalt_ld4l_cache_validation.yml +37 -0
  103. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/oclc_fast_validation.yml +71 -5
  104. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/oclcfast_direct_validation.yml +73 -2
  105. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/oclcfast_ld4l_cache_validation.yml +73 -0
  106. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/rda_registry_ld4l_cache_validation.yml +307 -0
  107. data/lib/qa_server/configuration.rb +28 -24
  108. data/lib/qa_server/version.rb +1 -1
  109. data/qa_server.gemspec +6 -5
  110. data/spec/feature/accuracy_spec.rb +32 -0
  111. data/spec/i18n_spec.rb +36 -0
  112. data/spec/spec_helper.rb +4 -0
  113. metadata +74 -20
  114. data/app/cache_processors/qa_server/performance_daily_graph_cache.rb +0 -60
  115. data/app/cache_processors/qa_server/performance_hourly_graph_cache.rb +0 -65
  116. data/app/cache_processors/qa_server/performance_monthly_graph_cache.rb +0 -60
@@ -6,87 +6,93 @@ module QaServer
6
6
  class SearchScenarioValidator < ScenarioValidator
7
7
  SEARCH_ACTION = 'search'
8
8
 
9
+ # CONCRETE Implementation: Return value of request_data
10
+ attr_reader :request_data
11
+ private :request_data
12
+
9
13
  # @param scenario [SearchScenario] the scenario to run
10
14
  # @param status_log [ScenarioLogger] logger for recording test results
11
15
  # @param validation_type [Symbol] the type of scenarios to run (e.g. VALIDATE_CONNECTION, VALIDATE_ACCURACY, ALL_VALIDATIONS)
12
16
  def initialize(scenario:, status_log:, validation_type: DEFAULT_VALIDATION_TYPE)
13
17
  super
18
+ @request_data = scenario.query
14
19
  end
15
20
 
16
- private
21
+ private
17
22
 
18
- def action
19
- SEARCH_ACTION
20
- end
23
+ def action
24
+ SEARCH_ACTION
25
+ end
21
26
 
22
- # Run the connection test and log results
23
- def run_connection_scenario
24
- test_connection(min_expected_size: scenario.min_result_size, scenario_type_name: 'search') do
25
- replacements = scenario.replacements.dup
26
- authority.search(scenario.query,
27
- subauth: scenario.subauthority_name,
28
- replacements: replacements)
29
- end
27
+ # CONCRETE Implementation: Run the connection test and log results
28
+ def run_connection_scenario
29
+ test_connection(min_expected_size: scenario.min_result_size, scenario_type_name: 'search') do
30
+ replacements = scenario.replacements.dup
31
+ authority.search(scenario.query,
32
+ subauth: scenario.subauthority_name,
33
+ replacements: replacements)
30
34
  end
35
+ end
31
36
 
32
- # Run the accuracy test and log results
33
- def run_accuracy_scenario
34
- test_accuracy(subject_uri: scenario.subject_uri, expected_by_position: scenario.expected_by_position) do
35
- authority.search(scenario.query,
36
- subauth: scenario.subauthority_name,
37
- replacements: scenario.replacements)
38
- end
37
+ # CONCRETE Implementation: Run the accuracy test and log results
38
+ def run_accuracy_scenario
39
+ test_accuracy(subject_uri: scenario.subject_uri, expected_by_position: scenario.expected_by_position, pending: scenario.pending?) do
40
+ replacements = scenario.replacements.dup
41
+ authority.search(scenario.query,
42
+ subauth: scenario.subauthority_name,
43
+ replacements: replacements)
39
44
  end
45
+ end
40
46
 
41
- # Runs the accuracy test and log results
42
- def test_accuracy(subject_uri:, expected_by_position:)
43
- dt_start = QaServer::TimeService.current_time
44
- results = yield if block_given?
45
- dt_end = QaServer::TimeService.current_time
46
- if results.blank?
47
- log(status: UNKNOWN, errmsg: "Search position scenario failed; cause: no results found", expected: expected_by_position, target: subject_uri, request_run_time: (dt_end - dt_start))
48
- return
49
- end
50
-
51
- check_position(results, subject_uri, expected_by_position, total_run_time: (dt_end - dt_start)) # TODO: need to get run times from results
52
- rescue Exception => e
53
- dt_end = QaServer::TimeService.current_time
54
- log(status: FAIL, errmsg: "Exception executing search position scenario; cause: #{e.message}",
55
- expected: expected_by_position, target: subject_uri, request_run_time: (dt_end - dt_start))
47
+ # Runs the accuracy test and log results
48
+ def test_accuracy(subject_uri:, expected_by_position:, pending: false)
49
+ dt_start = QaServer::TimeService.current_time
50
+ results = yield if block_given?
51
+ dt_end = QaServer::TimeService.current_time
52
+ if results.blank?
53
+ log(status: UNKNOWN, errmsg: "Search position scenario failed; cause: no results found", expected: expected_by_position,
54
+ target: subject_uri, request_run_time: (dt_end - dt_start), pending: pending)
55
+ return
56
56
  end
57
57
 
58
- def accuracy_scenario?
59
- return false if scenario.expected_by_position.blank? || scenario.subject_uri.blank?
60
- true
61
- end
58
+ check_position(results, subject_uri, expected_by_position, total_run_time: (dt_end - dt_start), pending: pending) # TODO: need to get run times from results
59
+ rescue Exception => e
60
+ dt_end = QaServer::TimeService.current_time
61
+ log(status: FAIL, errmsg: "Exception executing search position scenario; cause: #{e.message}",
62
+ expected: expected_by_position, target: subject_uri, request_run_time: (dt_end - dt_start), pending: pending)
63
+ end
62
64
 
63
- def connection_scenario?
64
- # There are only two types of tests, so if this isn't an accuracy scenario, it must be a connection scenario.
65
- !accuracy_scenario?
66
- end
65
+ def accuracy_scenario?
66
+ return false if scenario.expected_by_position.blank? || scenario.subject_uri.blank?
67
+ true
68
+ end
67
69
 
68
- def check_position(results, subject_uri, expected_by_position, total_run_time)
69
- actual_position = subject_position(results, subject_uri, total_run_time)
70
- return if actual_position.blank?
70
+ def connection_scenario?
71
+ # There are only two types of tests, so if this isn't an accuracy scenario, it must be a connection scenario.
72
+ !accuracy_scenario?
73
+ end
71
74
 
72
- actual_position += 1
73
- if actual_position <= expected_by_position
74
- log(status: PASS, expected: expected_by_position, actual: actual_position, target: subject_uri,
75
- normalization_run_time: total_run_time) # TODO: need to get run times from results
76
- else
77
- log(status: UNKNOWN, errmsg: 'Subject URI not found by the expected position.',
78
- expected: expected_by_position, actual: actual_position, target: subject_uri,
79
- normalization_run_time: total_run_time) # TODO: need to get run times from results
80
- end
75
+ def check_position(results, subject_uri, expected_by_position, total_run_time:, pending:)
76
+ actual_position = subject_position(results, subject_uri, total_run_time, pending)
77
+ return if actual_position.blank?
78
+
79
+ if actual_position <= expected_by_position
80
+ log(status: PASS, expected: expected_by_position, actual: actual_position, target: subject_uri,
81
+ normalization_run_time: total_run_time, pending: pending) # TODO: need to get run times from results
82
+ else
83
+ log(status: UNKNOWN, errmsg: 'Subject URI not found by the expected position.',
84
+ expected: expected_by_position, actual: actual_position, target: subject_uri,
85
+ normalization_run_time: total_run_time, pending: pending) # TODO: need to get run times from results
81
86
  end
87
+ end
82
88
 
83
- def subject_position(results, subject_uri, total_run_time)
84
- 0.upto(results.size - 1) do |position|
85
- return position if results[position][:uri] == subject_uri
86
- end
87
- log(status: UNKNOWN, errmsg: "Search position scenario failed; cause: subject uri (#{subject_uri}) not found in results",
88
- expected: scenario.expected_by_position, target: subject_uri, normalization_run_time: total_run_time) # TODO: need to get run times from results
89
- nil
89
+ def subject_position(results, subject_uri, total_run_time, pending)
90
+ 0.upto(results.size - 1) do |position|
91
+ return position + 1 if results[position][:uri] == subject_uri
90
92
  end
93
+ log(status: UNKNOWN, errmsg: "Search position scenario failed; cause: subject uri (#{subject_uri}) not found in results",
94
+ expected: scenario.expected_by_position, target: subject_uri, normalization_run_time: total_run_time, pending: pending) # TODO: need to get run times from results
95
+ nil
96
+ end
91
97
  end
92
98
  end
@@ -4,14 +4,21 @@ module QaServer
4
4
  class TermScenarioValidator < ScenarioValidator
5
5
  TERM_ACTION = 'term'
6
6
 
7
+ # CONCRETE Implementation: Return value of request_data
8
+ attr_reader :request_data
9
+ private :request_data
10
+
7
11
  # @param scenario [TermScenario] the scenario to run
8
12
  # @param status_log [ScenarioLogger] logger for recording test results
9
13
  # @param validation_type [Symbol] the type of scenarios to run (e.g. VALIDATE_CONNECTION, VALIDATE_ACCURACY, ALL_VALIDATIONS)
10
14
  def initialize(scenario:, status_log:, validation_type: DEFAULT_VALIDATION_TYPE)
11
15
  super
16
+ @request_data = scenario.identifier
12
17
  end
13
18
 
14
- # Run a term scenario and log results.
19
+ private
20
+
21
+ # CONCRETE Implementation: Run a term scenario and log results.
15
22
  def run_connection_scenario
16
23
  test_connection(min_expected_size: scenario.min_result_size, scenario_type_name: 'term') do
17
24
  authority.find(scenario.identifier,
@@ -19,25 +26,23 @@ module QaServer
19
26
  end
20
27
  end
21
28
 
22
- # Run a term scenario and log results.
29
+ # CONCRETE Implementation: Run a term scenario and log results.
23
30
  def run_accuracy_scenario
24
31
  # no accuracy scenarios defined for terms at this time
25
32
  end
26
33
 
27
- private
28
-
29
- def action
30
- TERM_ACTION
31
- end
34
+ def action
35
+ TERM_ACTION
36
+ end
32
37
 
33
- def accuracy_scenario?
34
- # At this time, all scenarios are connection scenarios for terms.
35
- false
36
- end
38
+ def accuracy_scenario?
39
+ # At this time, all scenarios are connection scenarios for terms.
40
+ false
41
+ end
37
42
 
38
- def connection_scenario?
39
- # At this time, all scenarios are connection scenarios for terms.
40
- true
41
- end
43
+ def connection_scenario?
44
+ # At this time, all scenarios are connection scenarios for terms.
45
+ true
46
+ end
42
47
  end
43
48
  end
@@ -1,10 +1,35 @@
1
1
  <script>
2
+ function hide_data() {
3
+ connection_status_section = document.getElementById('connection-status-section');
4
+ if (connection_status_section != null) {
5
+ connection_status_section.style.display = 'none';
6
+ }
7
+ accuracy_status_section = document.getElementById('accuracy-status-section');
8
+ if (accuracy_status_section != null) {
9
+ accuracy_status_section.style.display = 'none';
10
+ }
11
+ comparison_status_section = document.getElementById('comparison-status-section');
12
+ if (comparison_status_section != null) {
13
+ comparison_status_section.style.display = 'none';
14
+ }
15
+ }
16
+
2
17
  function validate_authority(form) {
3
- form.submit();
18
+ show_loading_message();
19
+ hide_data();
20
+ }
21
+
22
+ function show_loading_message() {
4
23
  document.getElementById('status-loading-message').style.display = 'block';
5
- document.getElementById('connection-status-section').style.display = 'none';
6
- document.getElementById('accuracy-status-section').style.display = 'none';
7
- document.getElementById('example-url-warning').style.display = 'none';
24
+ }
25
+ function hide_loading_message() {
26
+ document.getElementById('status-loading-message').style.display = 'none';
27
+ }
28
+ function show_comparison_selector() {
29
+ document.getElementById('comparison-authority-selector').style.display = 'block';
30
+ }
31
+ function hide_comparison_selector() {
32
+ document.getElementById('comparison-authority-selector').style.display = 'none';
8
33
  }
9
34
  </script>
10
35
 
@@ -12,24 +37,43 @@
12
37
 
13
38
  <h2><%= t('qa_server.check_status.title') %></h2>
14
39
 
40
+ <% selected_authority = @presenter.selected_authority %>
41
+ <% selected_comparison = @presenter.selected_comparison %>
15
42
  <%= form_tag({ action: 'index' }, { method: :get }) do %>
16
- <select name="authority" id="authority" class="string multi-value optional form-control form-control multi-text-field" value="" aria-labelledby="authority" onchange="validate_authority(this.form)">
17
- <option value=""><%= t('qa_server.check_status.select_authority') %></option>
18
- <option disabled>──────────</option>
19
- <option value="<%= @presenter.value_all_collections %>"><%= t('qa_server.check_status.show_all') %></option>
20
- <option disabled>──────────</option>
21
- <% @authorities_list.each do |auth_name| %>
22
- <option value="<%= auth_name %>"><%= auth_name.upcase %></option>
23
- <% end %>
24
- </select>
25
- <div class="validation-types">
26
- <%= radio_button_tag(@presenter.value_check_param, @presenter.value_check_connections, :selected) %>
27
- <%= label_tag(@presenter.label_check_connections, t('qa_server.check_status.connections'), class: 'horizontal-list') %>
28
- <%= radio_button_tag(@presenter.value_check_param, @presenter.value_check_accuracy) %>
29
- <%= label_tag(@presenter.label_check_accuracy, t('qa_server.check_status.accuracy'), class: 'horizontal-list') %>
30
- <%= radio_button_tag(@presenter.value_check_param, @presenter.value_all_checks) %>
31
- <%= label_tag(@presenter.label_all_checks, t('qa_server.check_status.all_checks'), class: 'horizontal-list') %>
32
- </div>
43
+ <div id="authority-selector">
44
+ <select name="authority" id="authority" class="string optional form-control form-control" value="" aria-labelledby="authority" onchange="hide_data()">
45
+ <option value=""><%= t('qa_server.check_status.select_authority') %></option>
46
+ <option disabled>──────────</option>
47
+ <option value="<%= @presenter.value_all_collections %>"><%= t('qa_server.check_status.show_all') %></option>
48
+ <option disabled>──────────</option>
49
+ <% @authorities_list.each do |auth_name| %>
50
+ <option value="<%= auth_name %>"<%= " selected" if auth_name == selected_authority %>><%= auth_name.upcase %></option>
51
+ <% end %>
52
+ </select>
53
+ </div>
54
+
55
+ <div id="comparison-authority-selector" style="<%= "display\: block" if @presenter.comparison_status_data? %>">
56
+ Compare with:
57
+ <select name="compare_with" id="compare-with" class="string optional form-control form-control" value="" aria-labelledby="authority" onchange="hide_data()">
58
+ <option value=""><%= t('qa_server.check_status.select_authority') %></option>
59
+ <option disabled>──────────</option>
60
+ <% @authorities_list.each do |auth_name| %>
61
+ <option value="<%= auth_name %>"<%= " selected" if auth_name == selected_comparison %>><%= auth_name.upcase %></option>
62
+ <% end %>
63
+ </select>
64
+ </div>
65
+
66
+ <div class="validation-types">
67
+ <%= radio_button_tag(@presenter.value_check_param, @presenter.value_check_connections, @presenter.connection_tests_checked, onClick: "hide_comparison_selector()") %>
68
+ <%= label_tag(@presenter.label_check_connections, t('qa_server.check_status.connections'), class: 'horizontal-list') %>
69
+ <%= radio_button_tag(@presenter.value_check_param, @presenter.value_check_accuracy, @presenter.accuracy_tests_checked, onClick: "hide_comparison_selector()") %>
70
+ <%= label_tag(@presenter.label_check_accuracy, t('qa_server.check_status.accuracy'), class: 'horizontal-list') %>
71
+ <%= radio_button_tag(@presenter.value_check_param, @presenter.value_check_comparison, @presenter.comparison_tests_checked, onClick: "show_comparison_selector()") %>
72
+ <%= label_tag(@presenter.label_check_comparison, t('qa_server.check_status.comparison'), class: 'horizontal-list') %>
73
+ <%= radio_button_tag(@presenter.value_check_param, @presenter.value_all_checks, false, onClick: "hide_comparison_selector()") %>
74
+ <%= label_tag(@presenter.label_all_checks, t('qa_server.check_status.all_checks'), class: 'horizontal-list') %>
75
+ </div>
76
+ <button type="submit" class="btn btn-primary" id="check-status-go" onclick="validate_authority(this.form)">GO</button>
33
77
  <% end %>
34
78
 
35
79
 
@@ -56,7 +100,7 @@
56
100
  </tr>
57
101
  <% end %>
58
102
  <tr>
59
- <td class="<%= @presenter.status_style_class(status) %>"><%= @presenter.status_label(status) %></td>
103
+ <td class="<%= @presenter.status_style_class(status[:status]) %>"><%= @presenter.status_label(status[:status]) %></td>
60
104
  <td><%= status[:subauthority_name] %></td>
61
105
  <td><%= status[:service] %></td>
62
106
  <td><%= status[:action] %></td>
@@ -75,6 +119,7 @@
75
119
  <tr>
76
120
  <th><%= t('qa_server.check_status.status_table.expected_by_position') %></th>
77
121
  <th><%= t('qa_server.check_status.status_table.actual_position') %></th>
122
+ <th><%= t('qa_server.check_status.status_table.request_data') %></th>
78
123
  <th><%= t('qa_server.check_status.status_table.subject_uri') %></th>
79
124
  <th><%= t('qa_server.check_status.status_table.authority') %></th>
80
125
  <th><%= t('qa_server.check_status.status_table.subauthority') %></th>
@@ -83,10 +128,18 @@
83
128
  <th><%= t('qa_server.check_status.status_table.url') %></th>
84
129
  <th><%= t('qa_server.check_status.status_table.errmsg') %></th>
85
130
  </tr>
131
+ <% current_authority = nil %>
86
132
  <% @presenter.accuracy_status_data.each do |status| %>
133
+ <% unless status[:authority_name] == current_authority %>
134
+ <% current_authority = status[:authority_name] %>
135
+ <tr>
136
+ <td class="table_subheading" colspan="10"><%= current_authority %></td>
137
+ </tr>
138
+ <% end %>
87
139
  <tr>
88
- <td class="position <%= @presenter.status_style_class(status) %>"><%= status[:expected] %></td>
89
- <td class="position <%= @presenter.status_style_class(status) %>"><%= status[:actual] %></td>
140
+ <td class="position <%= @presenter.status_style_class(status[:status]) %>"><%= status[:expected] %></td>
141
+ <td class="position <%= @presenter.status_style_class(status[:status]) %>"><%= status[:actual] %></td>
142
+ <td><%= status[:request_data] %></td>
90
143
  <td><a href="<%= status[:target] %>"><%= status[:target] %></a></td>
91
144
  <td><%= status[:authority_name] %></td>
92
145
  <td><%= status[:subauthority_name] %></td>
@@ -100,4 +153,47 @@
100
153
  </div>
101
154
  <% end %>
102
155
 
156
+ <% if @presenter.comparison_status_data? %>
157
+ <div id="comparison-status-section" class="status-section">
158
+ <h3><%= t('qa_server.check_status.comparison_checks') %></h3>
159
+ <% auth_before = @presenter.comparison_status_data.first[:authority_name][0]%>
160
+ <% auth_after = @presenter.comparison_status_data.first[:authority_name][1]%>
161
+ <table class="status">
162
+ <tr>
163
+ <th class="comparison-header comparison-before bold-left-border" colspan=2><%= auth_before %><br><%= t('qa_server.check_status.status_table.before') %></th>
164
+ <th class="comparison-header comparison-after" colspan=2><%= auth_after %><br><%= t('qa_server.check_status.status_table.after') %></th>
165
+ <th class="comparison-header" colspan=7></th>
166
+ </tr>
167
+ <tr>
168
+ <th class="bold-left-border"><%= t('qa_server.check_status.status_table.expected_by_position') %></th>
169
+ <th><%= t('qa_server.check_status.status_table.actual_position') %></th>
170
+ <th class="bold-left-border"><%= t('qa_server.check_status.status_table.expected_by_position') %></th>
171
+ <th><%= t('qa_server.check_status.status_table.actual_position') %></th>
172
+ <th class="bold-left-border"><%= t('qa_server.check_status.status_table.request_data') %></th>
173
+ <th><%= t('qa_server.check_status.status_table.subject_uri') %></th>
174
+ <th><%= t('qa_server.check_status.status_table.subauthority') %></th>
175
+ <th><%= t('qa_server.check_status.status_table.service') %></th>
176
+ <th><%= t('qa_server.check_status.status_table.action') %></th>
177
+ <th><%= t('qa_server.check_status.status_table.url') %></th>
178
+ <th><%= t('qa_server.check_status.status_table.errmsg') %></th>
179
+ </tr>
180
+ <% @presenter.comparison_status_data.each do |status| %>
181
+ <tr>
182
+ <td class="position bold-left-border <%= @presenter.status_style_class(status[:status][0]) %>"><%= status[:expected][0] %></td>
183
+ <td class="position <%= @presenter.status_style_class(status[:status][0]) %>"><%= status[:actual][0] %></td>
184
+ <td class="position bold-left-border <%= @presenter.status_style_class(status[:status][1]) %>"><%= status[:expected][1] %></td>
185
+ <td class="position <%= @presenter.status_style_class(status[:status][1]) %>"><%= status[:actual][1] %></td>
186
+ <td class="bold-left-border"><%= status[:request_data] %></td>
187
+ <td><a href="<%= status[:target] %>"><%= status[:target] %></a></td>
188
+ <td><%= status[:subauthority_name] %></td>
189
+ <td><%= status[:service] %></td>
190
+ <td><%= status[:action] %></td>
191
+ <td><a href="<%= status[:url][0] %>"><%= status[:url][0] %></a>, <a href="<%= status[:url][1] %>"><%= status[:url][1] %></a></td>
192
+ <td><%= status[:err_message] %></td>
193
+ </tr>
194
+ <% end %>
195
+ </table>
196
+ </div>
197
+ <% end %>
198
+
103
199
  </div>
@@ -17,7 +17,7 @@
17
17
  <td class="status-neutral"><%= @presenter.tests_count %></td>
18
18
  </tr>
19
19
  </table>
20
- <p class="status-update-dtstamp"><%= t('qa_server.monitor_status.summary.last_updated', date: @presenter.last_updated) %></p>
20
+ <p class="status-update-dtstamp"><%= @presenter.last_updated %></p>
21
21
 
22
22
  <% if @presenter.failures?%>
23
23
  <div id="failures" class="status-section">
@@ -0,0 +1,133 @@
1
+ # i18n-tasks finds and manages missing and unused translations: https://github.com/glebm/i18n-tasks
2
+
3
+ # The "main" locale.
4
+ base_locale: en
5
+ ## All available locales are inferred from the data by default. Alternatively, specify them explicitly:
6
+ # locales: [es, fr]
7
+ ## Reporting locale, default: en. Available: en, ru.
8
+ # internal_locale: en
9
+
10
+ # Read and write translations.
11
+ data:
12
+ ## Translations are read from the file system. Supported format: YAML, JSON.
13
+ ## Provide a custom adapter:
14
+ # adapter: I18n::Tasks::Data::FileSystem
15
+
16
+ # Locale files or `File.find` patterns where translations are read from:
17
+ read:
18
+ ## Default:
19
+ # - config/locales/%{locale}.yml
20
+ ## More files:
21
+ - config/locales/**/*.%{locale}.yml
22
+
23
+ # Locale files to write new keys to, based on a list of key pattern => file rules. Matched from top to bottom:
24
+ # `i18n-tasks normalize -p` will force move the keys according to these rules
25
+ write:
26
+ ## For example, write devise and simple form keys to their respective files:
27
+ # - ['{devise, simple_form}.*', 'config/locales/\1.%{locale}.yml']
28
+ ## Catch-all default:
29
+ # - config/locales/%{locale}.yml
30
+
31
+ # External locale data (e.g. gems).
32
+ # This data is not considered unused and is never written to.
33
+ external:
34
+ ## Example (replace %#= with %=):
35
+ # - "<%#= %x[bundle show vagrant].chomp %>/templates/locales/%{locale}.yml"
36
+
37
+ ## Specify the router (see Readme for details). Valid values: conservative_router, pattern_router, or a custom class.
38
+ # router: conservative_router
39
+
40
+ yaml:
41
+ write:
42
+ # do not wrap lines at 80 characters
43
+ line_width: -1
44
+
45
+ ## Pretty-print JSON:
46
+ # json:
47
+ # write:
48
+ # indent: ' '
49
+ # space: ' '
50
+ # object_nl: "\n"
51
+ # array_nl: "\n"
52
+
53
+ # Find translate calls
54
+ search:
55
+ ## Paths or `File.find` patterns to search in:
56
+ # paths:
57
+ # - app/
58
+
59
+ ## Root directories for relative keys resolution.
60
+ # relative_roots:
61
+ # - app/controllers
62
+ # - app/helpers
63
+ # - app/mailers
64
+ # - app/presenters
65
+ # - app/views
66
+
67
+ ## Files or `File.fnmatch` patterns to exclude from search. Some files are always excluded regardless of this setting:
68
+ ## %w(*.jpg *.png *.gif *.svg *.ico *.eot *.otf *.ttf *.woff *.woff2 *.pdf *.css *.sass *.scss *.less *.yml *.json)
69
+ exclude:
70
+ - app/assets/images
71
+ - app/assets/fonts
72
+ - app/assets/videos
73
+
74
+ ## Alternatively, the only files or `File.fnmatch patterns` to search in `paths`:
75
+ ## If specified, this settings takes priority over `exclude`, but `exclude` still applies.
76
+ # only: ["*.rb", "*.html.slim"]
77
+
78
+ ## If `strict` is `false`, guess usages such as t("categories.#{category}.title"). The default is `true`.
79
+ # strict: true
80
+
81
+ ## Multiple scanners can be used. Their results are merged.
82
+ ## The options specified above are passed down to each scanner. Per-scanner options can be specified as well.
83
+ ## See this example of a custom scanner: https://github.com/glebm/i18n-tasks/wiki/A-custom-scanner-example
84
+
85
+ ## Translation Services
86
+ # translation:
87
+ # # Google Translate
88
+ # # Get an API key and set billing info at https://code.google.com/apis/console to use Google Translate
89
+ # google_translate_api_key: "AbC-dEf5"
90
+ # # DeepL Pro Translate
91
+ # # Get an API key and subscription at https://www.deepl.com/pro to use DeepL Pro
92
+ # deepl_api_key: "48E92789-57A3-466A-9959-1A1A1A1A1A1A"
93
+
94
+ ## Do not consider these keys missing:
95
+ # ignore_missing:
96
+ # - 'errors.messages.{accepted,blank,invalid,too_short,too_long}'
97
+ # - '{devise,simple_form}.*'
98
+
99
+ ## Consider these keys used:
100
+ # ignore_unused:
101
+ # - 'activerecord.attributes.*'
102
+ # - '{devise,kaminari,will_paginate}.*'
103
+ # - 'simple_form.{yes,no}'
104
+ # - 'simple_form.{placeholders,hints,labels}.*'
105
+ # - 'simple_form.{error_notification,required}.:'
106
+
107
+ ## Exclude these keys from the `i18n-tasks eq-base' report:
108
+ # ignore_eq_base:
109
+ # all:
110
+ # - common.ok
111
+ # fr,es:
112
+ # - common.brand
113
+
114
+ ## Exclude these keys from the `i18n-tasks check-consistent-interpolations` report:
115
+ # ignore_inconsistent_interpolations:
116
+ # - 'activerecord.attributes.*'
117
+
118
+ ## Ignore these keys completely:
119
+ # ignore:
120
+ # - kaminari.*
121
+
122
+ ## Sometimes, it isn't possible for i18n-tasks to match the key correctly,
123
+ ## e.g. in case of a relative key defined in a helper method.
124
+ ## In these cases you can use the built-in PatternMapper to map patterns to keys, e.g.:
125
+ #
126
+ # <%# I18n::Tasks.add_scanner 'I18n::Tasks::Scanners::PatternMapper',
127
+ # only: %w(*.html.haml *.html.slim),
128
+ # patterns: [['= title\b', '.page_title']] %>
129
+ #
130
+ # The PatternMapper can also match key literals via a special %{key} interpolation, e.g.:
131
+ #
132
+ # <%# I18n::Tasks.add_scanner 'I18n::Tasks::Scanners::PatternMapper',
133
+ # patterns: [['\bSpree\.t[( ]\s*%{key}', 'spree.%{key}']] %>