qa_server 0.1.99

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +71 -0
  3. data/Gemfile +55 -0
  4. data/Gemfile.lock +411 -0
  5. data/LICENSE +201 -0
  6. data/README.md +187 -0
  7. data/Rakefile +18 -0
  8. data/app/assets/images/qa_server/LD4L-bg.png +0 -0
  9. data/app/assets/images/qa_server/cornell-reduced-white.svg +160 -0
  10. data/app/assets/images/qa_server/iowa-logo.png +0 -0
  11. data/app/assets/images/qa_server/samvera-fall-font1-1000w-light.png +0 -0
  12. data/app/assets/javascripts/qa_server.js +0 -0
  13. data/app/assets/stylesheets/qa_server/_authorities.scss +0 -0
  14. data/app/assets/stylesheets/qa_server/_check-status.scss +72 -0
  15. data/app/assets/stylesheets/qa_server/_footer.scss +20 -0
  16. data/app/assets/stylesheets/qa_server/_header.scss +51 -0
  17. data/app/assets/stylesheets/qa_server/_home-page.scss +15 -0
  18. data/app/assets/stylesheets/qa_server/_monitor-status.scss +13 -0
  19. data/app/assets/stylesheets/qa_server/_qa_server.scss +36 -0
  20. data/app/assets/stylesheets/qa_server/_styles.scss +27 -0
  21. data/app/assets/stylesheets/qa_server/_usage.scss +0 -0
  22. data/app/controllers/qa_server/authority_list_controller.rb +14 -0
  23. data/app/controllers/qa_server/authority_validation_controller.rb +77 -0
  24. data/app/controllers/qa_server/check_status_controller.rb +38 -0
  25. data/app/controllers/qa_server/homepage_controller.rb +8 -0
  26. data/app/controllers/qa_server/monitor_status_controller.rb +79 -0
  27. data/app/controllers/qa_server/usage_controller.rb +8 -0
  28. data/app/loggers/qa_server/scenario_logger.rb +84 -0
  29. data/app/models/qa_server/authority_scenario.rb +35 -0
  30. data/app/models/qa_server/authority_status.rb +18 -0
  31. data/app/models/qa_server/authority_status_failure.rb +7 -0
  32. data/app/models/qa_server/scenarios.rb +71 -0
  33. data/app/models/qa_server/search_scenario.rb +58 -0
  34. data/app/models/qa_server/term_scenario.rb +50 -0
  35. data/app/presenters/qa_server/authority_list_presenter.rb +22 -0
  36. data/app/presenters/qa_server/check_status_presenter.rb +96 -0
  37. data/app/presenters/qa_server/monitor_status_presenter.rb +108 -0
  38. data/app/services/qa_server/authority_lister_service.rb +31 -0
  39. data/app/services/qa_server/authority_loader_service.rb +38 -0
  40. data/app/services/qa_server/authority_validator_service.rb +41 -0
  41. data/app/services/qa_server/database_migrator.rb +70 -0
  42. data/app/services/qa_server/scenarios_loader_service.rb +57 -0
  43. data/app/validators/qa_server/scenario_validator.rb +134 -0
  44. data/app/validators/qa_server/search_scenario_validator.rb +84 -0
  45. data/app/validators/qa_server/term_scenario_validator.rb +42 -0
  46. data/app/views/layouts/qa_server.html.erb +65 -0
  47. data/app/views/qa_server/authority_list/index.html.erb +27 -0
  48. data/app/views/qa_server/check_status/index.html.erb +104 -0
  49. data/app/views/qa_server/homepage/index.html.erb +10 -0
  50. data/app/views/qa_server/monitor_status/index.html.erb +78 -0
  51. data/app/views/qa_server/usage/index.html.erb +106 -0
  52. data/app/views/shared/_footer.html.erb +24 -0
  53. data/config/locales/qa_server.en.yml +68 -0
  54. data/config/routes.rb +12 -0
  55. data/lib/generators/qa_server/assets_generator.rb +35 -0
  56. data/lib/generators/qa_server/config_generator.rb +31 -0
  57. data/lib/generators/qa_server/install_generator.rb +60 -0
  58. data/lib/generators/qa_server/models_generator.rb +18 -0
  59. data/lib/generators/qa_server/templates/config/authorities/linked_data/agrovoc_direct.json +69 -0
  60. data/lib/generators/qa_server/templates/config/authorities/linked_data/agrovoc_ld4l_cache.json +85 -0
  61. data/lib/generators/qa_server/templates/config/authorities/linked_data/dbpedia_direct.json +36 -0
  62. data/lib/generators/qa_server/templates/config/authorities/linked_data/dbpedia_ld4l_cache.json +83 -0
  63. data/lib/generators/qa_server/templates/config/authorities/linked_data/geonames_direct.json +68 -0
  64. data/lib/generators/qa_server/templates/config/authorities/linked_data/geonames_ld4l_cache.json +102 -0
  65. data/lib/generators/qa_server/templates/config/authorities/linked_data/getty_aat_ld4l_cache.json +109 -0
  66. data/lib/generators/qa_server/templates/config/authorities/linked_data/getty_tgn_ld4l_cache.json +72 -0
  67. data/lib/generators/qa_server/templates/config/authorities/linked_data/getty_ulan_ld4l_cache.json +81 -0
  68. data/lib/generators/qa_server/templates/config/authorities/linked_data/loc_direct.json +47 -0
  69. data/lib/generators/qa_server/templates/config/authorities/linked_data/locgenres_ld4l_cache.json +99 -0
  70. data/lib/generators/qa_server/templates/config/authorities/linked_data/locnames_ld4l_cache.json +89 -0
  71. data/lib/generators/qa_server/templates/config/authorities/linked_data/locsubjects_ld4l_cache.json +82 -0
  72. data/lib/generators/qa_server/templates/config/authorities/linked_data/mesh_ld4l_cache.json +70 -0
  73. data/lib/generators/qa_server/templates/config/authorities/linked_data/nalt_direct.json +32 -0
  74. data/lib/generators/qa_server/templates/config/authorities/linked_data/nalt_ld4l_cache.json +84 -0
  75. data/lib/generators/qa_server/templates/config/authorities/linked_data/oclcfast_direct.json +81 -0
  76. data/lib/generators/qa_server/templates/config/authorities/linked_data/oclcfast_ld4l_cache.json +86 -0
  77. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/agrovoc_direct_validation.yml +9 -0
  78. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/agrovoc_ld4l_cache_validation.yml +9 -0
  79. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/agrovoc_validation.yml +9 -0
  80. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/dbpedia_direct_validation.yml +6 -0
  81. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/dbpedia_ld4l_cache_validation.yml +9 -0
  82. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/geonames_direct_validation.yml +9 -0
  83. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/geonames_ld4l_cache_validation.yml +41 -0
  84. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/getty_aat_ld4l_cache_validation.yml +115 -0
  85. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/getty_tgn_ld4l_cache_validation.yml +9 -0
  86. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/getty_ulan_ld4l_cache_validation.yml +15 -0
  87. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/loc_direct_validation.yml +25 -0
  88. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/loc_validation.yml +22 -0
  89. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/locgenres_ld4l_cache_validation.yml +99 -0
  90. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/locnames_ld4l_cache_validation.yml +27 -0
  91. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/locsubjects_ld4l_cache_validation.yml +27 -0
  92. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/mesh_ld4l_cache_validation.yml +9 -0
  93. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/nalt_direct_validation.yml +6 -0
  94. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/nalt_ld4l_cache_validation.yml +9 -0
  95. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/oclc_fast_validation.yml +58 -0
  96. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/oclcfast_direct_validation.yml +58 -0
  97. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/oclcfast_ld4l_cache_validation.yml +30 -0
  98. data/lib/generators/qa_server/templates/config/locales/qa_server.en.yml +9 -0
  99. data/lib/generators/qa_server/templates/db/migrate/20180313045551_create_cron_authority_status.rb.erb +9 -0
  100. data/lib/generators/qa_server/templates/db/migrate/20180508045549_rename_cron_authority_status_to_authority_status.rb.erb +5 -0
  101. data/lib/generators/qa_server/templates/db/migrate/20180508045551_create_authority_status_failure.rb.erb +15 -0
  102. data/lib/generators/qa_server/templates/qa_server.scss +5 -0
  103. data/lib/qa_server/engine.rb +19 -0
  104. data/lib/qa_server/version.rb +3 -0
  105. data/lib/qa_server.rb +6 -0
  106. data/lib/tasks/install.rake +8 -0
  107. data/lib/tasks/qa_server_tasks.rake +4 -0
  108. data/qa_server.gemspec +39 -0
  109. data/spec/.gitignore +1 -0
  110. data/spec/rails_helper.rb +2 -0
  111. data/spec/spec_helper.rb +283 -0
  112. data/spec/test_app_templates/Gemfile.extra +5 -0
  113. data/spec/test_app_templates/lib/generators/test_app_generator.rb +15 -0
  114. data/tasks/qa_server_dev.rake +16 -0
  115. metadata +275 -0
@@ -0,0 +1,134 @@
1
+ # ABSTRACT class providing common methods for running a scenario of any type.
2
+ module QaServer
3
+ class ScenarioValidator
4
+ PASS = :good
5
+ FAIL = :bad
6
+ UNKNOWN = :unknown
7
+
8
+ VALIDATE_CONNECTION = :connection
9
+ VALIDATE_ACCURACY = :accuracy
10
+ ALL_VALIDATIONS = :all_validations
11
+ DEFAULT_VALIDATION_TYPE = VALIDATE_CONNECTION
12
+
13
+ # @param scenario [SearchScenario | TermScenario] the scenario to run
14
+ # @param status_log [ScenarioLogger] logger for recording test results
15
+ # @param validation_type [Symbol] the type of scenarios to run (e.g. VALIDATE_CONNECTION, VALIDATE_ACCURACY, ALL_VALIDATIONS)
16
+ def initialize(scenario:, status_log:, validation_type: DEFAULT_VALIDATION_TYPE)
17
+ @status_log = status_log
18
+ @scenario = scenario
19
+ @validation_type = validation_type
20
+ end
21
+
22
+ # Run a search scenario and log results.
23
+ def run
24
+ run_accuracy_scenario if accuracy_scenario? && validating_accuracy?
25
+ run_connection_scenario if connection_scenario? && validating_connections?
26
+ end
27
+
28
+ # Log the structure of the scenario without running the scenario test.
29
+ def log_without_running
30
+ log
31
+ end
32
+
33
+ private
34
+
35
+ # Log the structure of the scenario and status of a test run.
36
+ def log(status: nil, errmsg: nil, expected: nil, actual: nil, target: nil)
37
+ status_log.add(authority_name: authority_name,
38
+ status: status,
39
+ validation_type: scenario_validation_type,
40
+ subauth: subauthority_name,
41
+ service: service,
42
+ action: action,
43
+ url: url,
44
+ error_message: errmsg,
45
+ expected: expected,
46
+ actual: actual,
47
+ target: target)
48
+ end
49
+
50
+ def run_accuracy_scenario
51
+ # ABSTRACT - must be implemented by scenario validator for specific types
52
+ end
53
+
54
+ def run_connection_scenario
55
+ # ABSTRACT - must be implemented by scenario validator for specific types
56
+ end
57
+
58
+ # Runs the test in the block passed by the specific scenario type.
59
+ # @return [Symbol] :good (PASS) or :unknown (UNKNOWN) based on whether enough results were returned
60
+ def test_connection(min_expected_size: MIN_EXPECTED_SIZE, scenario_type_name:)
61
+ begin
62
+ results = yield if block_given?
63
+ actual_size = results.to_s.length
64
+ status = actual_size > min_expected_size ? PASS : UNKNOWN
65
+ errmsg = (status == PASS) ? '' : "#{scenario_type_name.capitalize} scenario unknown status; cause: Results actual size (#{actual_size} < expected size (#{min_expected_size})"
66
+ log(status: status, errmsg: errmsg)
67
+ rescue Exception => e
68
+ log(status: FAIL, errmsg: "Exception executing #{scenario_type_name} scenario; cause: #{e.message}")
69
+ end
70
+ end
71
+
72
+ def authority
73
+ scenario.authority
74
+ end
75
+
76
+ def authority_name
77
+ scenario.authority_name.upcase
78
+ end
79
+
80
+ def subauthority_name
81
+ scenario.subauthority_name
82
+ end
83
+
84
+ def service
85
+ scenario.service
86
+ end
87
+
88
+ def url
89
+ scenario.url
90
+ end
91
+
92
+ def action
93
+ # ABSTRACT - must be implemented by scenario validator for specific types
94
+ end
95
+
96
+ def status_log
97
+ @status_log
98
+ end
99
+
100
+ def scenario
101
+ @scenario
102
+ end
103
+
104
+ def validation_type
105
+ @validation_type
106
+ end
107
+
108
+ def scenario_validation_type
109
+ return VALIDATE_CONNECTION if connection_scenario?
110
+ return VALIDATE_ACCURACY if accuracy_scenario?
111
+ nil
112
+ end
113
+
114
+ def validating_connections?
115
+ return true if validation_type == VALIDATE_CONNECTION || validation_type == ALL_VALIDATIONS
116
+ false
117
+ end
118
+
119
+ def validating_accuracy?
120
+ return true if validation_type == VALIDATE_ACCURACY || validation_type == ALL_VALIDATIONS
121
+ false
122
+ end
123
+
124
+ def accuracy_scenario?
125
+ # ABSTRACT define in specific scenario type validator (i.e. TermScenarioValidator, SearchScenarioValidator)
126
+ false
127
+ end
128
+
129
+ def connection_scenario?
130
+ # ABSTRACT define in specific scenario type validator (i.e. TermScenarioValidator, SearchScenarioValidator)
131
+ false
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,84 @@
1
+ require 'json'
2
+
3
+ # This class runs a single search scenario and logs the results.
4
+ module QaServer
5
+ class SearchScenarioValidator < ScenarioValidator
6
+ SEARCH_ACTION = 'search'.freeze
7
+
8
+ # @param scenario [SearchScenario] the scenario to run
9
+ # @param status_log [ScenarioLogger] logger for recording test results
10
+ # @param validation_type [Symbol] the type of scenarios to run (e.g. VALIDATE_CONNECTION, VALIDATE_ACCURACY, ALL_VALIDATIONS)
11
+ def initialize(scenario:, status_log:, validation_type: DEFAULT_VALIDATION_TYPE)
12
+ super
13
+ end
14
+
15
+ private
16
+
17
+ def action
18
+ SEARCH_ACTION
19
+ end
20
+
21
+ # Run the connection test and log results
22
+ def run_connection_scenario
23
+ test_connection(min_expected_size: scenario.min_result_size, scenario_type_name: 'search') do
24
+ authority.search(scenario.query,
25
+ subauth: scenario.subauthority_name,
26
+ replacements: scenario.replacements)
27
+ end
28
+ end
29
+
30
+ # Run the accuracy test and log results
31
+ def run_accuracy_scenario
32
+ test_accuracy(subject_uri: scenario.subject_uri, expected_by_position: scenario.expected_by_position) do
33
+ authority.search(scenario.query,
34
+ subauth: scenario.subauthority_name,
35
+ replacements: scenario.replacements)
36
+ end
37
+ end
38
+
39
+ # Runs the accuracy test and log results
40
+ def test_accuracy(subject_uri:, expected_by_position:)
41
+ begin
42
+ results = yield if block_given?
43
+ if results.blank?
44
+ log(status: UNKNOWN, errmsg: "Search position scenario failed; cause: no results found", expected: expected_by_position, target: subject_uri)
45
+ return
46
+ end
47
+
48
+ check_position(results, subject_uri, expected_by_position)
49
+ rescue Exception => e
50
+ log(status: FAIL, errmsg: "Exception executing search position scenario; cause: #{e.message}", expected: expected_by_position, target: subject_uri)
51
+ end
52
+ end
53
+
54
+ def accuracy_scenario?
55
+ return false if scenario.expected_by_position.blank? || scenario.subject_uri.blank?
56
+ true
57
+ end
58
+
59
+ def connection_scenario?
60
+ # There are only two types of tests, so if this isn't an accuracy scenario, it must be a connection scenario.
61
+ !accuracy_scenario?
62
+ end
63
+
64
+ def check_position(results, subject_uri, expected_by_position)
65
+ actual_position = subject_position(results, subject_uri)
66
+ return if actual_position.blank?
67
+
68
+ actual_position += 1
69
+ if actual_position <= expected_by_position
70
+ log(status: PASS, expected: expected_by_position, actual: actual_position, target: subject_uri)
71
+ else
72
+ log(status: UNKNOWN, errmsg: 'Subject URI not found by the expected position.', expected: expected_by_position, actual: actual_position, target: subject_uri)
73
+ end
74
+ end
75
+
76
+ def subject_position(results, subject_uri)
77
+ 0.upto(results.size - 1) do |position|
78
+ return position if results[position][:uri] == subject_uri
79
+ end
80
+ log(status: UNKNOWN, errmsg: "Search position scenario failed; cause: subject uri (#{subject_uri}) not found in results", expected: scenario.expected_by_position, target: subject_uri)
81
+ return nil
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,42 @@
1
+ # This class runs a single term scenario and logs the results.
2
+ module QaServer
3
+ class TermScenarioValidator < ScenarioValidator
4
+ TERM_ACTION = 'term'.freeze
5
+
6
+ # @param scenario [TermScenario] the scenario to run
7
+ # @param status_log [ScenarioLogger] logger for recording test results
8
+ # @param validation_type [Symbol] the type of scenarios to run (e.g. VALIDATE_CONNECTION, VALIDATE_ACCURACY, ALL_VALIDATIONS)
9
+ def initialize(scenario:, status_log:, validation_type: DEFAULT_VALIDATION_TYPE)
10
+ super
11
+ end
12
+
13
+ # Run a term scenario and log results.
14
+ def run_connection_scenario
15
+ test_connection(min_expected_size: scenario.min_result_size, scenario_type_name: 'term') do
16
+ authority.find(scenario.identifier,
17
+ subauth: scenario.subauthority_name)
18
+ end
19
+ end
20
+
21
+ # Run a term scenario and log results.
22
+ def run_accuracy_scenario
23
+ # no accuracy scenarios defined for terms at this time
24
+ end
25
+
26
+ private
27
+
28
+ def action
29
+ TERM_ACTION
30
+ end
31
+
32
+ def accuracy_scenario?
33
+ # At this time, all scenarios are connection scenarios for terms.
34
+ false
35
+ end
36
+
37
+ def connection_scenario?
38
+ # At this time, all scenarios are connection scenarios for terms.
39
+ true
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,65 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Authority Lookup Server</title>
5
+
6
+ <!-- Latest compiled and minified CSS -->
7
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
8
+ <!-- jQuery library -->
9
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
10
+ <!-- Latest compiled JavaScript -->
11
+ <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
12
+
13
+ <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
14
+ <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
15
+
16
+ <%= csrf_meta_tags %>
17
+
18
+ </head>
19
+
20
+ <body>
21
+ <section class="ld4l-identity" aria-label="Cornell" role="banner">
22
+ <div id="skiptocontent"><a href="#maincontent">skip to main content</a></div>
23
+ <div class="container">
24
+ <a href="<%= main_app.root_path %>"><img src="<%= image_url('qa_server/LD4L-bg.png') %>" class="header-logo"></a>
25
+ <a id="logo" class="navbar-brand" href="<%= main_app.root_path %>" data-no-turbolink="true">
26
+ <span class="institution-name"><%= t("qa_server.application_name") %></span>
27
+ </a>
28
+ </div> <!-- /container -->
29
+ </section>
30
+
31
+ <div class="container">
32
+ <nav id="masthead" class="navbar navbar-inverse navbar-static-top" role="navigation">
33
+ <div class="container-fluid">
34
+ <div class="navbar-header">
35
+ <ul class="nav-menu">
36
+ <li class="left-menu"><%= link_to t("qa_server.menu.home"), main_app.root_path %></li>
37
+ <li class="left-menu"><%= link_to t("qa_server.menu.usage"), qa_server.usage_index_path %></li>
38
+ <li class="left-menu"><%= link_to t("qa_server.menu.authorities"), qa_server.authority_list_index_path %></li>
39
+ <li class="left-menu"><%= link_to t("qa_server.menu.check_status"), qa_server.check_status_index_path %></li>
40
+ <li class="left-menu"><%= link_to t("qa_server.menu.monitor_status"), qa_server.monitor_status_index_path %></li>
41
+ <li class="right-menu"><%= link_to "LD4L Gateway", "http://ld4l.org/" %></li>
42
+ </ul>
43
+ </div>
44
+ </div>
45
+ </nav>
46
+ </div>
47
+ </div>
48
+
49
+ <div id="content-wrapper" class="container" role="main">
50
+ <a name="skip_to_content"></a>
51
+ <%# = render '/flash_msg' %>
52
+ <% if content_for?(:page_header) %>
53
+ <div class="row">
54
+ <div class="col-xs-12 main-header">
55
+ <%= yield(:page_header) %>
56
+ </div>
57
+ </div>
58
+ <% end %>
59
+
60
+ <%= content_for?(:content) ? yield(:content) : yield %>
61
+ </div><!-- /#content-wrapper -->
62
+ <%= render 'shared/footer' %>
63
+ <%# = render 'shared/ajax_modal' %>
64
+ </body>
65
+ </html>
@@ -0,0 +1,27 @@
1
+ <div class="page-description">
2
+
3
+ <h2><%= t('qa_server.authority_list.title') %></h2>
4
+ <p><%= t('qa_server.authority_list.see_check_status_html', href: "#{main_app.root_path}check_status") %></p>
5
+
6
+ <div id="status-section" class="status-section">
7
+ <p><b><%= t('qa_server.warning.chrome_unencoding_msg') %></b></p>
8
+ <table class="status">
9
+ <tr>
10
+ <th><%= t('qa_server.authority_list.data.authority') %></th>
11
+ <th><%= t('qa_server.authority_list.data.subauthority') %></th>
12
+ <th><%= t('qa_server.authority_list.data.service') %></th>
13
+ <th><%= t('qa_server.authority_list.data.action') %></th>
14
+ <th><%= t('qa_server.authority_list.data.url') %></th>
15
+ </tr>
16
+ <% @presenter.urls_data.each do |entry| %>
17
+ <tr>
18
+ <td><%= entry[:authority_name] %></td>
19
+ <td><%= entry[:subauthority_name] %></td>
20
+ <td><%= entry[:service] %></td>
21
+ <td><%= entry[:action] %></td>
22
+ <td><a href="<%= entry[:url] %>"><%= entry[:url] %></a></td>
23
+ </tr>
24
+ <% end %>
25
+ </table>
26
+ </div>
27
+ </div>
@@ -0,0 +1,104 @@
1
+ <script>
2
+ function validate_authority(form) {
3
+ form.submit();
4
+ 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';
8
+ }
9
+ </script>
10
+
11
+ <div class="page-description">
12
+
13
+ <h2><%= t('qa_server.check_status.title') %></h2>
14
+
15
+ <%= 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>
33
+ <% end %>
34
+
35
+
36
+ <div id="status-loading-message" class="wait-message"><%= t('qa_server.check_status.wait_message') %></div>
37
+
38
+ <% if @presenter.connection_status_data? || @presenter.accuracy_status_data? %>
39
+ <div id="example-url-warning">
40
+ <p><b><%= t('qa_server.warning.chrome_unencoding_msg') %></b></p>
41
+ </div>
42
+ <% end %>
43
+
44
+ <% if @presenter.connection_status_data? %>
45
+ <div id="connection-status-section" class="status-section">
46
+ <h3><%= t('qa_server.check_status.connection_checks') %></h3>
47
+ <table class="status">
48
+ <tr>
49
+ <th><%= t('qa_server.check_status.status_table.status') %></th>
50
+ <th><%= t('qa_server.check_status.status_table.authority') %></th>
51
+ <th><%= t('qa_server.check_status.status_table.subauthority') %></th>
52
+ <th><%= t('qa_server.check_status.status_table.service') %></th>
53
+ <th><%= t('qa_server.check_status.status_table.action') %></th>
54
+ <th><%= t('qa_server.check_status.status_table.url') %></th>
55
+ <th><%= t('qa_server.check_status.status_table.errmsg') %></th>
56
+ </tr>
57
+ <% @presenter.connection_status_data.each do |status| %>
58
+ <tr>
59
+ <td class="<%= @presenter.status_style_class(status) %>"><%= status[:status_label] %></td>
60
+ <td><%= status[:authority_name] %></td>
61
+ <td><%= status[:subauthority_name] %></td>
62
+ <td><%= status[:service] %></td>
63
+ <td><%= status[:action] %></td>
64
+ <td><a href="<%= status[:url] %>"><%= status[:url] %></a></td>
65
+ <td><%= status[:err_message] %></td>
66
+ </tr>
67
+ <% end %>
68
+ </table>
69
+ </div>
70
+ <% end %>
71
+
72
+ <% if @presenter.accuracy_status_data? %>
73
+ <div id="accuracy-status-section" class="status-section">
74
+ <h3><%= t('qa_server.check_status.accuracy_checks') %></h3>
75
+ <table class="status">
76
+ <tr>
77
+ <th><%= t('qa_server.check_status.status_table.expected_by_position') %></th>
78
+ <th><%= t('qa_server.check_status.status_table.actual_position') %></th>
79
+ <th><%= t('qa_server.check_status.status_table.subject_uri') %></th>
80
+ <th><%= t('qa_server.check_status.status_table.authority') %></th>
81
+ <th><%= t('qa_server.check_status.status_table.subauthority') %></th>
82
+ <th><%= t('qa_server.check_status.status_table.service') %></th>
83
+ <th><%= t('qa_server.check_status.status_table.action') %></th>
84
+ <th><%= t('qa_server.check_status.status_table.url') %></th>
85
+ <th><%= t('qa_server.check_status.status_table.errmsg') %></th>
86
+ </tr>
87
+ <% @presenter.accuracy_status_data.each do |status| %>
88
+ <tr>
89
+ <td class="position <%= @presenter.status_style_class(status) %>"><%= status[:expected] %></td>
90
+ <td class="position <%= @presenter.status_style_class(status) %>"><%= status[:actual] %></td>
91
+ <td><a href="<%= status[:target] %>"><%= status[:target] %></a></td>
92
+ <td><%= status[:authority_name] %></td>
93
+ <td><%= status[:subauthority_name] %></td>
94
+ <td><%= status[:service] %></td>
95
+ <td><%= status[:action] %></td>
96
+ <td><a href="<%= status[:url] %>"><%= status[:url] %></a></td>
97
+ <td><%= status[:err_message] %></td>
98
+ </tr>
99
+ <% end %>
100
+ </table>
101
+ </div>
102
+ <% end %>
103
+
104
+ </div>
@@ -0,0 +1,10 @@
1
+ <div class="page-description">
2
+ <p class="welcome">This service provides authority <b>lookup for single terms</b> and <b>search for terms</b> matching a query.
3
+ See <a href="<%= "#{main_app.root_path}usage" %>">Usage</a> for more information.</p>
4
+ <p class="welcome2">It has been created as part of the
5
+ <a href="http://ld4l.org" target="_blank">LD4L Labs project</a>, and is operated by
6
+ <a href="http://www.library.cornell.edu/" target="_blank">Cornell University Library</a>
7
+ in collaboration with the
8
+ <a href="https://www.slis.uiowa.edu/" target="_blank">School of Library and Information Science, University of Iowa</a>.
9
+ This work was funded through a grant from the <a href="https://mellon.org/" target="_blank">Andrew W. Mellon Foundation</a>.</p>
10
+ </div>
@@ -0,0 +1,78 @@
1
+ <div class="page-description">
2
+ <h2><%= t('qa_server.monitor_status.summary.title') %></h2>
3
+
4
+ <table class="monitor-status-status">
5
+ <tr>
6
+ <th><%= t('qa_server.monitor_status.summary.authorities') %></th>
7
+ <th><%= t('qa_server.monitor_status.summary.authorities_with_failures') %></th>
8
+ <th><%= t('qa_server.monitor_status.summary.passing_tests') %></th>
9
+ <th><%= t('qa_server.monitor_status.summary.failing_tests') %></th>
10
+ <th><%= t('qa_server.monitor_status.summary.total_tests') %></th>
11
+ </tr>
12
+ <tr>
13
+ <td><%= @presenter.authorities_count %></td>
14
+ <td class="<%= @presenter.authorities_count_style %>"><%= @presenter.failing_authorities_count %></td>
15
+ <td><%= @presenter.passing_tests_count%></td>
16
+ <td class="<%= @presenter.failing_tests_style %>"><%= @presenter.failing_tests_count %></td>
17
+ <td><%= @presenter.tests_count %></td>
18
+ </tr>
19
+ </table>
20
+ <p class="status-update-dtstamp"><%= t('qa_server.monitor_status.summary.last_updated', date: @presenter.last_updated) %></p>
21
+
22
+ <% if @presenter.failures? %>
23
+ <div id="status-section" class="status-section">
24
+ <h2><%= t('qa_server.monitor_status.failures.title') %></h2>
25
+
26
+ <p><b><%= t('qa_server.warning.chrome_unencoding_msg') %></b></p>
27
+ <table class="status">
28
+ <tr>
29
+ <th><%= t('qa_server.monitor_status.failures.status') %></th>
30
+ <th><%= t('qa_server.monitor_status.failures.authority') %></th>
31
+ <th><%= t('qa_server.monitor_status.failures.subauthority') %></th>
32
+ <th><%= t('qa_server.monitor_status.failures.service') %></th>
33
+ <th><%= t('qa_server.monitor_status.failures.action') %></th>
34
+ <th><%= t('qa_server.monitor_status.failures.url') %></th>
35
+ <th><%= t('qa_server.monitor_status.failures.errmsg') %></th>
36
+ </tr>
37
+ <% @status_data.each do |status| %>
38
+ <tr>
39
+ <td class="<%= "status-#{status[:status].to_s}" %>"><%= status[:status_label] %></td>
40
+ <td><%= status[:authority_name] %></td>
41
+ <td><%= status[:subauthority_name] %></td>
42
+ <td><%= status[:service] %></td>
43
+ <td><%= status[:action] %></td>
44
+ <td><a href="<%= status[:url] %>"><%= status[:url] %></a></td>
45
+ <td><%= status[:err_message] %></td>
46
+ </tr>
47
+ <% end %>
48
+ </table>
49
+ </div>
50
+ <% end %>
51
+
52
+ <% if @presenter.history? %>
53
+ <div id="status-section" class="status-section">
54
+ <h2><%= t('qa_server.monitor_status.history.title') %></h2>
55
+
56
+ <h3><%= t('qa_server.monitor_status.history.since', date: @presenter.first_updated) %></h3>
57
+
58
+ <table class="status">
59
+ <tr>
60
+ <th><%= t('qa_server.monitor_status.history.days_failing') %></th>
61
+ <th><%= t('qa_server.monitor_status.history.authority') %></th>
62
+ <th><%= t('qa_server.monitor_status.history.subauthority') %></th>
63
+ <th><%= t('qa_server.monitor_status.history.service') %></th>
64
+ <th><%= t('qa_server.monitor_status.history.action') %></th>
65
+ </tr>
66
+ <% @presenter.history.each do |entry| %>
67
+ <tr>
68
+ <td><%= entry[:days_failing] %></td>
69
+ <td><%= entry[:authority_name] %></td>
70
+ <td><%= entry[:subauthority_name] %></td>
71
+ <td><%= entry[:service] %></td>
72
+ <td><%= entry[:action] %></td>
73
+ </tr>
74
+ <% end %>
75
+ </table>
76
+ </div>
77
+ <% end %>
78
+ </div>
@@ -0,0 +1,106 @@
1
+ <div class="page-description">
2
+
3
+ <h2>Usage:</h2>
4
+ <h3>To search for matching terms:</h3>
5
+
6
+ <p>The query parameter <b>q</b> is required. All other parameters are optional. Some authorities support different
7
+ optional parameters, but attempts were made to keep optional parameter names consistent between authorities.</p>
8
+
9
+ <h4>Without subauthority:</h4>
10
+ <pre>/<%= QaServer::QA_ENGINE_MOUNT %>/search/linked_data/locnames_ld4l_cache?q=mark%20twain&maxRecords=4&lang=en</pre>
11
+
12
+ where,
13
+ <ul>
14
+ <li>search (required) - indicates this is a query for terms</li>
15
+ <li>locnames_ld4l_cache (required) - the name of the authority</li>
16
+ <li>q=mark twain (required) - the query for which to search</li>
17
+ <li>maxRecords=4 (optional) - the number of results to return</li>
18
+ <li>lang=en (optional) - if the authority returns language encoded literals, results will be filtered for English
19
+ </ul>
20
+
21
+ <h4>With subauthority</h4>
22
+ <pre>/<%= QaServer::QA_ENGINE_MOUNT %>/search/linked_data/locnames_ld4l_cache/person?q=mark%20twain&maxRecords=4&lang=en</pre>
23
+
24
+ where,
25
+ <ul>
26
+ <li>search (required) - indicates this is a query for terms</li>
27
+ <li>locnames_ld4l_cache (required) - the name of the authority</li>
28
+ <li>person (optional) - limits results to this subauthority (meaning of subauthoritites is authority dependent)</li>
29
+ <li>q=mark twain (required) - the query for which to search</li>
30
+ <li>maxRecords=4 (optional) - the number of results to return</li>
31
+ <li>lang=en (optional) - if the authority returns language encoded literals, results will be filtered for the specified language
32
+ </ul>
33
+
34
+ <h4>Results format:</h4>
35
+ <p>The results minimally contain the uri, id, and label for each result found. The uri and id may be the same, but not
36
+ in all cases.</p>
37
+
38
+ <p>Example of results with two terms found:</p>
39
+ <pre>
40
+ [
41
+ {
42
+ "uri":"http://id.loc.gov/authorities/names/n92016188",
43
+ "id":"http://id.loc.gov/authorities/names/n92016188",
44
+ "label":"Twain, Mark, 1835-1910. Mark Twain papers"
45
+ },
46
+ {
47
+ "uri":"http://id.loc.gov/authorities/names/n42025440",
48
+ "id":"http://id.loc.gov/authorities/names/n42025440",
49
+ "label":"Twain, Mark, 1835-1910. Mark Twain library"
50
+ }
51
+ ]</pre>
52
+
53
+ <hr>
54
+ <h3>To fetch a single term:</h3>
55
+
56
+ <p>The data after the authority name is required and should be the URI or the ID of the term being retrieved.
57
+ Which value to use depends on the authority configuration. All other parameters are optional. Some
58
+ authorities support different optional parameters, but attempts were made to keep optional parameter names
59
+ consistent between authorities.</p>
60
+
61
+ <h4>Fetch by URI</h4>
62
+ <pre>/<%= QaServer::QA_ENGINE_MOUNT %>/show/linked_data/locnames_ld4l_cache/http%3A%2F%2Fid%2Eloc%2Egov%2Fauthorities%2Fnames%2Fn92016188</pre>
63
+ <p><b><%= t('qa_server.warning.chrome_unencoding_msg') %></b></p>
64
+
65
+ where,
66
+ <ul>
67
+ <li>show (required) - indicates this is a fetch of a single term</li>
68
+ <li>locnames_ld4l_cache (required) - the name of the authority</li>
69
+ <li>http%3A%2F%2Fid%2Eloc%2Egov%2Fauthorities%2Fnames%2Fn92016188 (required) - the encoded uri of the term to fetch</li>
70
+ <li>lang=en (optional) - if the authority returns language encoded literals, results will be filtered for the specified language</li>
71
+ </ul>
72
+
73
+ <h4>Fetch by ID</h4>
74
+ <pre>/<%= QaServer::QA_ENGINE_MOUNT %>/show/linked_data/oclcfast_ld4l_cache/1914919?lang=en</pre>
75
+
76
+ where,
77
+ <ul>
78
+ <li>show (required) - indicates this is a fetch of a single term</li>
79
+ <li>oclcfast_ld4l_cache (required) - the name of the authority</li>
80
+ <li>1914919 (required) - the id of the term to fetch</li>
81
+ <li>lang=en (optional) - if the authority returns language encoded literals, results will be filtered for the specified language
82
+ </ul>
83
+
84
+ <h4>Results format:</h4>
85
+ <p>The results minimally contain the uri, id, and label of the term. The uri and id may be the same, but not
86
+ in all cases. All predicate and object values where the term is the subject are also returned in the predicates list.</p>
87
+
88
+ <p>Example results for a fetch of a term:</p>
89
+ <pre>
90
+ {
91
+ "uri":"http://id.worldcat.org/fast/530369",
92
+ "id":"530369",
93
+ "label":"Cornell University",
94
+ "altlabel":["Ithaca (N.Y.). Cornell University"],
95
+ "sameas":["http://id.loc.gov/authorities/names/n79021621","https://viaf.org/viaf/126293486"],
96
+ "predicates":{
97
+ "http://purl.org/dc/terms/identifier":"530369",
98
+ "http://www.w3.org/2004/02/skos/core#inScheme":["http://id.worldcat.org/fast/ontology/1.0/#fast","http://id.worldcat.org/fast/ontology/1.0/#facet-Corporate"],
99
+ "http://www.w3.org/1999/02/22-rdf-syntax-ns#type":"http://schema.org/Organization",
100
+ "http://www.w3.org/2004/02/skos/core#prefLabel":"Cornell University",
101
+ "http://schema.org/name":["Cornell University","Ithaca (N.Y.). Cornell University"],
102
+ "http://www.w3.org/2004/02/skos/core#altLabel":["Ithaca (N.Y.). Cornell University"],
103
+ "http://schema.org/sameAs":["http://id.loc.gov/authorities/names/n79021621","https://viaf.org/viaf/126293486"]
104
+ }
105
+ }</pre>
106
+ </div>