qa 5.3.0 → 5.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.md +99 -73
- data/app/services/qa/linked_data/authority_url_service.rb +1 -1
- data/app/services/qa/linked_data/request_header_service.rb +7 -2
- data/config/authorities/linked_data/oclc_fast.json +5 -5
- data/lib/qa/authorities/geonames.rb +30 -4
- data/lib/qa/authorities/linked_data/find_term.rb +2 -2
- data/lib/qa/authorities/linked_data/search_query.rb +2 -2
- data/lib/qa/authorities/loc/generic_authority.rb +2 -2
- data/lib/qa/version.rb +1 -1
- data/spec/controllers/linked_data_terms_controller_spec.rb +9 -9
- data/spec/controllers/terms_controller_spec.rb +2 -2
- data/spec/lib/authorities/geonames_spec.rb +30 -2
- data/spec/lib/authorities/getty/aat_spec.rb +2 -2
- data/spec/lib/authorities/getty/tgn_spec.rb +2 -2
- data/spec/lib/authorities/linked_data/find_term_spec.rb +6 -6
- data/spec/lib/authorities/loc_spec.rb +9 -9
- data/spec/lib/mesh_data_parser_spec.rb +2 -2
- data/spec/services/linked_data/authority_url_service_spec.rb +9 -3
- metadata +34 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 427d2d24aab8a8c5a9453dd96aa0f677143ec993f98efb098fdb772c5b5ba429
|
4
|
+
data.tar.gz: 7d71a7cfa524b2d12a7b657e11fc0144db1795b48c65690391fc81a5ec2f93af
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c5c375b7b54a7e08f7eff73a473542d36a748ebb0298bad65a91b06177479861d762cdf79d08c72a453fa44df8b94094524bd94a03105bbeb3975873e4a299bc
|
7
|
+
data.tar.gz: 205775aa62254267b41f07f6bb3ec5b7f5d5a5f684a70742182b6edc3e77eb406066d6ce829b61f24780d624b7d609fe75832b844bca7e9bf8d2051cfa00517e
|
data/README.md
CHANGED
@@ -1,77 +1,83 @@
|
|
1
1
|
# Questioning Authority
|
2
2
|
|
3
|
-
Code:
|
4
|
-
[](http://badge.fury.io/rb/qa)
|
5
|
-
[](https://circleci.com/gh/samvera/questioning_authority)
|
6
|
-
[](https://coveralls.io/github/samvera/questioning_authority?branch=master)
|
3
|
+
Code: [](http://badge.fury.io/rb/qa) [](https://circleci.com/gh/samvera/questioning_authority) [](https://coveralls.io/github/samvera/questioning_authority?branch=master)
|
7
4
|
|
8
|
-
Docs:
|
9
|
-
[](./CONTRIBUTING.md)
|
10
|
-
[](./LICENSE)
|
5
|
+
Docs: [](./CONTRIBUTING.md) [](./LICENSE)
|
11
6
|
|
12
7
|
Jump In: [](http://slack.samvera.org/)
|
13
8
|
|
14
9
|
You should question your authorities.
|
15
10
|
|
16
|
-
|
11
|
+
--------------------------------------------------------------------------------
|
12
|
+
|
17
13
|
## Table of Contents
|
18
14
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
15
|
+
- [What does this do?](#what-does-this-do)
|
16
|
+
- [How does it work?](#how-does-it-work)
|
17
|
+
|
18
|
+
- [Sub-Authorities](#sub-authorities)
|
19
|
+
|
20
|
+
- [How do I use this?](#how-do-i-use-this)
|
21
|
+
|
22
|
+
- [Basic QA Requests](#basic-qa-requests)
|
23
|
+
- [Typical JSON Results](#typical-json-results)
|
24
|
+
|
25
|
+
- [Authority Sources information](#authority-sources-information)
|
26
|
+
|
27
|
+
- [Developer Notes](#developer-notes)
|
28
|
+
|
29
|
+
- [Compatibility](#compatibility)
|
30
|
+
- [Product Owner & Maintenance](#product-owner--maintenance)
|
31
|
+
|
32
|
+
- [Product Owner](#product-owner)
|
33
|
+
|
34
|
+
- [Help](#help)
|
35
|
+
|
36
|
+
- [Acknowledgments](#acknowledgments)
|
37
|
+
|
38
|
+
## Not seeing documentation you used to find in the README?
|
39
|
+
|
40
|
+
Much of the documentation has moved to the [Questioning Authority wiki](https://github.com/samvera/questioning_authority/wiki) to allow for better organization. We hope that you will find this easier to use.
|
41
|
+
|
42
|
+
--------------------------------------------------------------------------------
|
43
|
+
|
38
44
|
## What does this do?
|
39
45
|
|
40
|
-
Provides a set of uniform RESTful routes to query any controlled vocabulary or set of authority terms.
|
41
|
-
Results are returned in JSON and can be used within the context of a Rails application or any other
|
42
|
-
Ruby environment. Primary examples would include providing auto-complete functionality via Javascript
|
43
|
-
or populating a dropdown menu with a set of terms.
|
46
|
+
Provides a set of uniform RESTful routes to query any controlled vocabulary or set of authority terms. Results are returned in JSON and can be used within the context of a Rails application or any other Ruby environment. Primary examples would include providing auto-complete functionality via Javascript or populating a dropdown menu with a set of terms.
|
44
47
|
|
45
48
|
## How does it work?
|
46
49
|
|
47
|
-
Authorities are defined as classes, each implementing a set of methods allowing a controller to return
|
48
|
-
results from a given vocabulary in the JSON format. The controller does three things:
|
50
|
+
Authorities are defined as classes, each implementing a set of methods allowing a controller to return results from a given vocabulary in the JSON format. The controller does three things:
|
49
51
|
|
50
|
-
|
51
|
-
|
52
|
-
|
52
|
+
- provide a list of all terms (if allowed by the class)
|
53
|
+
- return a set of terms matching a given query
|
54
|
+
- return the complete information for a specific term given its identifier
|
53
55
|
|
54
|
-
Depending on the kind of authority or its API, the controller may not do all of these things such
|
55
|
-
as return a complete list of terms.
|
56
|
+
Depending on the kind of authority or its API, the controller may not do all of these things such as return a complete list of terms.
|
56
57
|
|
57
58
|
### Sub-Authorities
|
58
59
|
|
59
|
-
Some authorities, such as Library of Congress, allow sub-authorities which is an additional parameter that
|
60
|
-
further defines the kind of authority to use with the context of a larger one.
|
60
|
+
Some authorities, such as Library of Congress, allow sub-authorities which is an additional parameter that further defines the kind of authority to use with the context of a larger one.
|
61
61
|
|
62
62
|
## How do I use this?
|
63
63
|
|
64
64
|
Add the gem to your Gemfile
|
65
65
|
|
66
|
-
|
66
|
+
```
|
67
|
+
gem 'qa'
|
68
|
+
```
|
67
69
|
|
68
70
|
Run bundler
|
69
71
|
|
70
|
-
|
72
|
+
```
|
73
|
+
bundle install
|
74
|
+
```
|
71
75
|
|
72
76
|
Install the gem to your application
|
73
77
|
|
74
|
-
|
78
|
+
```
|
79
|
+
rails generate qa:install
|
80
|
+
```
|
75
81
|
|
76
82
|
This will copy over some additional config files and add the engine's routes to your `config/route.rb`.
|
77
83
|
|
@@ -79,84 +85,104 @@ Start questioning your authorities!
|
|
79
85
|
|
80
86
|
### Basic QA Requests
|
81
87
|
|
82
|
-
These show the basic routing patterns for connecting to authorities.
|
88
|
+
These show the basic routing patterns for connecting to authorities. See the [Questioning Authority wiki](https://github.com/samvera/questioning_authority/wiki) documentation for detailed documentation and examples for each authority and local authorities.
|
83
89
|
|
84
90
|
Return a complete list of terms:
|
85
91
|
|
86
|
-
|
87
|
-
|
92
|
+
```
|
93
|
+
/qa/terms/:vocab
|
94
|
+
/qa/terms/:vocab/:subauthority
|
95
|
+
```
|
88
96
|
|
89
97
|
Return a set of terms matching a given query
|
90
98
|
|
91
|
-
|
92
|
-
|
99
|
+
```
|
100
|
+
/qa/search/:vocab?q=search_term
|
101
|
+
/qa/search/:vocab/:subauthority?q=search_term
|
102
|
+
```
|
93
103
|
|
94
104
|
Return the complete information for a specific term given its identifier
|
95
105
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
106
|
+
```
|
107
|
+
/qa/show/:vocab/:id
|
108
|
+
/qa/show/:vocab/:subauthority/:id
|
109
|
+
```
|
100
110
|
|
101
111
|
### Typical JSON Results
|
102
112
|
|
103
113
|
Results are returned in JSON in this format:
|
104
114
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
115
|
+
```
|
116
|
+
[
|
117
|
+
{"id" : "subject_id_1", "label" : "First labels"},
|
118
|
+
{"id" : "subject_id_2", "label" : "Printing labels"},
|
119
|
+
{"id" : "", "label" : "This term has no id number"},
|
120
|
+
{"id" : "", "label" : "Neither does this"}
|
121
|
+
]
|
122
|
+
```
|
112
123
|
|
113
124
|
# Authority Sources information
|
114
125
|
|
115
126
|
See the [Questioning Authority wiki](https://github.com/samvera/questioning_authority/wiki) for documentation on how to connect to the supported authorities, documentation on how to create new authorities, and other useful tips.
|
116
127
|
|
117
|
-
|
118
128
|
# Developer Notes
|
119
129
|
|
120
130
|
[How to Contribute](./CONTRIBUTING.md)
|
121
131
|
|
122
132
|
To develop this gem, clone the repository, then run:
|
123
133
|
|
124
|
-
|
125
|
-
|
134
|
+
```
|
135
|
+
bundle install
|
136
|
+
rake ci
|
137
|
+
```
|
126
138
|
|
127
|
-
This will install the gems, create a dummy application under spec/internal and run the tests.
|
128
|
-
make sure you've included tests and run the test suite with a new sample application:
|
139
|
+
This will install the gems, create a dummy application under spec/internal and run the tests. After you've made changes, make sure you've included tests and run the test suite with a new sample application:
|
129
140
|
|
130
|
-
|
131
|
-
|
141
|
+
```
|
142
|
+
rake engine_cart:clean
|
143
|
+
rake ci
|
144
|
+
```
|
132
145
|
|
133
146
|
Commit your features into a new branch and submit a pull request.
|
134
147
|
|
135
148
|
## Compatibility
|
136
149
|
|
137
|
-
|
138
|
-
|
150
|
+
- Ruby 2.5 or the latest 2.4 version is recommended. Later versions may also work.
|
151
|
+
- Rails 5 is required. We recommend the latest Rails 5.2 release.
|
139
152
|
|
140
153
|
## Product Owner & Maintenance
|
141
154
|
|
142
|
-
Questioning Authority is a Core Component of the Samvera community. The documentation for
|
143
|
-
what this means can be found [here](http://samvera.github.io/core_components.html#requirements-for-a-core-component).
|
155
|
+
Questioning Authority is a Core Component of the Samvera community. The documentation for what this means can be found [here](http://samvera.github.io/core_components.html#requirements-for-a-core-component).
|
144
156
|
|
145
157
|
### Product Owner
|
146
158
|
|
147
159
|
[elrayle](https://github.com/elrayle)
|
148
160
|
|
161
|
+
## Releasing
|
162
|
+
|
163
|
+
1. `bundle install`
|
164
|
+
2. Increase the version number in `lib/qa/version.rb`
|
165
|
+
3. Increase the same version number in `.github_changelog_generator`
|
166
|
+
4. Update `CHANGELOG.md` by running this command:
|
167
|
+
|
168
|
+
```
|
169
|
+
github_changelog_generator --user samvera --project questioning_authority --token YOUR_GITHUB_TOKEN_HERE
|
170
|
+
```
|
171
|
+
|
172
|
+
5. Commit these changes to the master branch
|
173
|
+
|
174
|
+
6. Run `rake release`
|
175
|
+
|
149
176
|
# Help
|
150
177
|
|
151
178
|
The Samvera community is here to help. Please see our [support guide](./SUPPORT.md).
|
152
179
|
|
153
180
|
# Acknowledgments
|
154
181
|
|
155
|
-
This software has been developed by and is brought to you by the Samvera community.
|
156
|
-
[Samvera website](http://samvera.org/).
|
182
|
+
This software has been developed by and is brought to you by the Samvera community. Learn more at the [Samvera website](http://samvera.org/).
|
157
183
|
|
158
184
|

|
159
185
|
|
160
|
-
|
186
|
+
## Special thanks to...
|
161
187
|
|
162
188
|
[Jeremy Friesen](https://github.com/jeremyf) who gave us the name for our gem.
|
@@ -29,7 +29,7 @@ module Qa
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def combined_substitutions(action_config, action, action_request, request_header)
|
32
|
-
substitutions = request_header.fetch(:replacements, {})
|
32
|
+
substitutions = request_header.fetch(:replacements, {}).clone
|
33
33
|
substitutions[action_request_variable(action_config, action)] = action_request
|
34
34
|
substitutions[action_subauth_variable(action_config)] = action_subauth_variable_value(action_config, request_header)
|
35
35
|
substitutions[action_language_variable(action_config)] = language_value(action_config, request_header)
|
@@ -70,9 +70,14 @@ module Qa
|
|
70
70
|
private
|
71
71
|
|
72
72
|
def log_request
|
73
|
-
gc = request.location
|
74
73
|
msg = "******** #{request.path_parameters[:action].upcase}"
|
75
|
-
|
74
|
+
unless Qa.config.suppress_ip_data_from_log
|
75
|
+
gc = request.respond_to?(:location) ? request.location : nil
|
76
|
+
city = gc.nil? ? "UNKNOWN" : gc.city
|
77
|
+
state = gc.nil? ? "UNKNOWN" : gc.state
|
78
|
+
country = gc.nil? ? "UNKNOWN" : gc.country
|
79
|
+
msg += " from IP #{request.ip} in {city: #{city}, state: #{state}, country: #{country}}"
|
80
|
+
end
|
76
81
|
Rails.logger.info(msg)
|
77
82
|
end
|
78
83
|
|
@@ -2,14 +2,13 @@
|
|
2
2
|
"QA_CONFIG_VERSION": "2.1",
|
3
3
|
"prefixes": {
|
4
4
|
"dcterms": "http://purl.org/dc/terms/",
|
5
|
-
"
|
6
|
-
"schema": "http://schema.org/"
|
5
|
+
"schema": "http://schema.org/"
|
7
6
|
},
|
8
7
|
"term": {
|
9
8
|
"url": {
|
10
9
|
"@context": "http://www.w3.org/ns/hydra/context.jsonld",
|
11
10
|
"@type": "IriTemplate",
|
12
|
-
"template": "http://id.worldcat.org/fast/{term_id}",
|
11
|
+
"template": "http://id.worldcat.org/fast/{term_id}.rdf.xml",
|
13
12
|
"variableRepresentation": "BasicRepresentation",
|
14
13
|
"mapping": [
|
15
14
|
{
|
@@ -35,14 +34,15 @@
|
|
35
34
|
"url": {
|
36
35
|
"@context": "http://www.w3.org/ns/hydra/context.jsonld",
|
37
36
|
"@type": "IriTemplate",
|
38
|
-
"template": "http://experimental.worldcat.org/fast/search?query={subauth}+all+%22{query}%22&sortKeys=usage&{
|
37
|
+
"template": "http://experimental.worldcat.org/fast/search?query={subauth}+all+%22{query}%22&sortKeys=usage&maximumRecords={maximumRecords}",
|
39
38
|
"variableRepresentation": "BasicRepresentation",
|
40
39
|
"mapping": [
|
41
40
|
{
|
42
41
|
"@type": "IriTemplateMapping",
|
43
42
|
"variable": "query",
|
44
43
|
"property": "hydra:freetextQuery",
|
45
|
-
"required": true
|
44
|
+
"required": true,
|
45
|
+
"encode": true
|
46
46
|
},
|
47
47
|
{
|
48
48
|
"@type": "IriTemplateMapping",
|
@@ -2,7 +2,33 @@ module Qa::Authorities
|
|
2
2
|
class Geonames < Base
|
3
3
|
include WebServiceBase
|
4
4
|
|
5
|
-
class_attribute :username, :label
|
5
|
+
class_attribute :username, :label, :query_url_host, :find_url_host
|
6
|
+
|
7
|
+
# You may need to change your query_url_host in your implementation. To do
|
8
|
+
# so, in the installed application's config/initializers/qa.rb add the
|
9
|
+
# following:
|
10
|
+
#
|
11
|
+
# @example
|
12
|
+
# Qa::Authorities::Geonames.query_url_host = "http://ws.geonames.net"
|
13
|
+
#
|
14
|
+
# @note This is not exposed as part of the configuration block, but is
|
15
|
+
# something you can add after the configuration block.
|
16
|
+
# @todo Expose this magic value as a configuration option; Which likely
|
17
|
+
# requires consideration about how to do this for the general case
|
18
|
+
self.query_url_host = "http://api.geonames.org"
|
19
|
+
|
20
|
+
# You may need to change your query_url_host in your implementation. To do
|
21
|
+
# so, in the installed application's config/initializers/qa.rb add the
|
22
|
+
# following:
|
23
|
+
#
|
24
|
+
# @example
|
25
|
+
# Qa::Authorities::Geonames.find_url_host = "http://ws.geonames.net"
|
26
|
+
#
|
27
|
+
# @note This is not exposed as part of the configuration block, but is
|
28
|
+
# something you can add after the configuration block.
|
29
|
+
# @todo Expose this magic value as a configuration option; Which likely
|
30
|
+
# requires consideration about how to do this for the general case
|
31
|
+
self.find_url_host = "http://www.geonames.org"
|
6
32
|
|
7
33
|
self.label = lambda do |item|
|
8
34
|
[item['name'], item['adminName1'], item['countryName']].compact.join(', ')
|
@@ -18,7 +44,7 @@ module Qa::Authorities
|
|
18
44
|
|
19
45
|
def build_query_url(q)
|
20
46
|
query = ERB::Util.url_encode(untaint(q))
|
21
|
-
"
|
47
|
+
File.join(query_url_host, "searchJSON?q=#{query}&username=#{username}&maxRows=10")
|
22
48
|
end
|
23
49
|
|
24
50
|
def untaint(q)
|
@@ -30,7 +56,7 @@ module Qa::Authorities
|
|
30
56
|
end
|
31
57
|
|
32
58
|
def find_url(id)
|
33
|
-
"
|
59
|
+
File.join(find_url_host, "getJSON?geonameId=#{id}&username=#{username}")
|
34
60
|
end
|
35
61
|
|
36
62
|
private
|
@@ -39,7 +65,7 @@ module Qa::Authorities
|
|
39
65
|
def parse_authority_response(response)
|
40
66
|
response['geonames'].map do |result|
|
41
67
|
# Note: the trailing slash is meaningful.
|
42
|
-
{ 'id' => "
|
68
|
+
{ 'id' => "https://sws.geonames.org/#{result['geonameId']}/",
|
43
69
|
'label' => label.call(result) }
|
44
70
|
end
|
45
71
|
end
|
@@ -112,8 +112,8 @@ module Qa::Authorities
|
|
112
112
|
predicate_map = preds_for_term
|
113
113
|
ldpath_map = ldpaths_for_term
|
114
114
|
|
115
|
-
raise Qa::InvalidConfiguration, "do not specify results using both predicates and ldpath in term configuration for linked data authority #{authority_name} (ldpath is preferred)" if predicate_map.present? && ldpath_map.present? # rubocop:disable
|
116
|
-
raise Qa::InvalidConfiguration, "must specify label_ldpath or label_predicate in term configuration for linked data authority #{authority_name} (label_ldpath is preferred)" unless ldpath_map.key?(:label) || predicate_map.key?(:label) # rubocop:disable
|
115
|
+
raise Qa::InvalidConfiguration, "do not specify results using both predicates and ldpath in term configuration for linked data authority #{authority_name} (ldpath is preferred)" if predicate_map.present? && ldpath_map.present? # rubocop:disable Layout/LineLength
|
116
|
+
raise Qa::InvalidConfiguration, "must specify label_ldpath or label_predicate in term configuration for linked data authority #{authority_name} (label_ldpath is preferred)" unless ldpath_map.key?(:label) || predicate_map.key?(:label) # rubocop:disable Layout/LineLength
|
117
117
|
|
118
118
|
if predicate_map.present?
|
119
119
|
Qa.deprecation_warning(
|
@@ -74,8 +74,8 @@ module Qa::Authorities
|
|
74
74
|
predicate_map = preds_for_search
|
75
75
|
ldpath_map = ldpaths_for_search
|
76
76
|
|
77
|
-
raise Qa::InvalidConfiguration, "do not specify results using both predicates and ldpath in search configuration for linked data authority #{authority_name} (ldpath is preferred)" if predicate_map.present? && ldpath_map.present? # rubocop:disable
|
78
|
-
raise Qa::InvalidConfiguration, "must specify label_ldpath or label_predicate in search configuration for linked data authority #{authority_name} (label_ldpath is preferred)" unless ldpath_map.key?(:label) || predicate_map.key?(:label) # rubocop:disable
|
77
|
+
raise Qa::InvalidConfiguration, "do not specify results using both predicates and ldpath in search configuration for linked data authority #{authority_name} (ldpath is preferred)" if predicate_map.present? && ldpath_map.present? # rubocop:disable Layout/LineLength
|
78
|
+
raise Qa::InvalidConfiguration, "must specify label_ldpath or label_predicate in search configuration for linked data authority #{authority_name} (label_ldpath is preferred)" unless ldpath_map.key?(:label) || predicate_map.key?(:label) # rubocop:disable Layout/LineLength
|
79
79
|
|
80
80
|
if predicate_map.present?
|
81
81
|
Qa.deprecation_warning(
|
@@ -26,7 +26,7 @@ module Qa::Authorities
|
|
26
26
|
def build_query_url(q)
|
27
27
|
escaped_query = ERB::Util.url_encode(q)
|
28
28
|
authority_fragment = Loc.get_url_for_authority(subauthority) + ERB::Util.url_encode(subauthority)
|
29
|
-
"
|
29
|
+
"https://id.loc.gov/search/?q=#{escaped_query}&q=#{authority_fragment}&format=json"
|
30
30
|
end
|
31
31
|
|
32
32
|
def find(id)
|
@@ -34,7 +34,7 @@ module Qa::Authorities
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def find_url(id)
|
37
|
-
"
|
37
|
+
"https://id.loc.gov/authorities/#{@subauthority}/#{id}.json"
|
38
38
|
end
|
39
39
|
|
40
40
|
private
|
data/lib/qa/version.rb
CHANGED
@@ -357,7 +357,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
|
|
357
357
|
context 'producing internal server error' do
|
358
358
|
context 'when server returns 500' do
|
359
359
|
before do
|
360
|
-
stub_request(:get, 'http://id.worldcat.org/fast/530369').to_return(status: 500)
|
360
|
+
stub_request(:get, 'http://id.worldcat.org/fast/530369.rdf.xml').to_return(status: 500)
|
361
361
|
end
|
362
362
|
it 'returns 500' do
|
363
363
|
expect(Rails.logger).to receive(:warn).with(graph_load_failure)
|
@@ -369,7 +369,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
|
|
369
369
|
|
370
370
|
context 'when data normalization error' do
|
371
371
|
before do
|
372
|
-
stub_request(:get, 'http://id.worldcat.org/fast/530369')
|
372
|
+
stub_request(:get, 'http://id.worldcat.org/fast/530369.rdf.xml')
|
373
373
|
.to_return(status: 200, body: webmock_fixture('lod_oclc_term_bad_id.nt'), headers: { 'Content-Type' => 'application/ntriples' })
|
374
374
|
end
|
375
375
|
it 'returns 500' do
|
@@ -381,7 +381,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
|
|
381
381
|
|
382
382
|
context 'when rdf format error' do
|
383
383
|
before do
|
384
|
-
stub_request(:get, 'http://id.worldcat.org/fast/530369').to_return(status: 200)
|
384
|
+
stub_request(:get, 'http://id.worldcat.org/fast/530369.rdf.xml').to_return(status: 200)
|
385
385
|
allow(RDF::Graph).to receive(:load).and_raise(RDF::FormatError)
|
386
386
|
end
|
387
387
|
it 'returns 500' do
|
@@ -395,7 +395,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
|
|
395
395
|
|
396
396
|
context "when error isn't specifically handled" do
|
397
397
|
before do
|
398
|
-
stub_request(:get, 'http://id.worldcat.org/fast/530369').to_return(status: 501)
|
398
|
+
stub_request(:get, 'http://id.worldcat.org/fast/530369.rdf.xml').to_return(status: 501)
|
399
399
|
end
|
400
400
|
it 'returns 500' do
|
401
401
|
expect(Rails.logger).to receive(:warn).with(graph_load_failure)
|
@@ -408,7 +408,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
|
|
408
408
|
|
409
409
|
context 'when service unavailable' do
|
410
410
|
before do
|
411
|
-
stub_request(:get, 'http://id.worldcat.org/fast/530369').to_return(status: 503)
|
411
|
+
stub_request(:get, 'http://id.worldcat.org/fast/530369.rdf.xml').to_return(status: 503)
|
412
412
|
end
|
413
413
|
it 'returns 503' do
|
414
414
|
expect(Rails.logger).to receive(:warn).with(graph_load_failure)
|
@@ -420,7 +420,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
|
|
420
420
|
|
421
421
|
context 'when requested term is not found at the server' do
|
422
422
|
before do
|
423
|
-
stub_request(:get, 'http://id.worldcat.org/fast/FAKE_ID').to_return(status: 404, body: '', headers: {})
|
423
|
+
stub_request(:get, 'http://id.worldcat.org/fast/FAKE_ID.rdf.xml').to_return(status: 404, body: '', headers: {})
|
424
424
|
end
|
425
425
|
it 'returns 404' do
|
426
426
|
expect(Rails.logger).to receive(:warn).with(graph_load_failure)
|
@@ -433,7 +433,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
|
|
433
433
|
context 'in OCLC_FAST authority' do
|
434
434
|
context 'term found' do
|
435
435
|
before do
|
436
|
-
stub_request(:get, 'http://id.worldcat.org/fast/530369')
|
436
|
+
stub_request(:get, 'http://id.worldcat.org/fast/530369.rdf.xml')
|
437
437
|
.to_return(status: 200, body: webmock_fixture('lod_oclc_term_found.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
|
438
438
|
end
|
439
439
|
it 'succeeds and defaults to json content type' do
|
@@ -481,7 +481,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
|
|
481
481
|
context 'when cors headers are enabled' do
|
482
482
|
before do
|
483
483
|
Qa.config.enable_cors_headers
|
484
|
-
stub_request(:get, 'http://id.worldcat.org/fast/530369')
|
484
|
+
stub_request(:get, 'http://id.worldcat.org/fast/530369.rdf.xml')
|
485
485
|
.to_return(status: 200, body: webmock_fixture('lod_oclc_term_found.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
|
486
486
|
end
|
487
487
|
it 'Access-Control-Allow-Origin is *' do
|
@@ -493,7 +493,7 @@ describe Qa::LinkedDataTermsController, type: :controller do
|
|
493
493
|
context 'when cors headers are disabled' do
|
494
494
|
before do
|
495
495
|
Qa.config.disable_cors_headers
|
496
|
-
stub_request(:get, 'http://id.worldcat.org/fast/530369')
|
496
|
+
stub_request(:get, 'http://id.worldcat.org/fast/530369.rdf.xml')
|
497
497
|
.to_return(status: 200, body: webmock_fixture('lod_oclc_term_found.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
|
498
498
|
end
|
499
499
|
it 'Access-Control-Allow-Origin is not present' do
|
@@ -82,7 +82,7 @@ describe Qa::TermsController, type: :controller do
|
|
82
82
|
|
83
83
|
context "loc" do
|
84
84
|
before do
|
85
|
-
stub_request(:get, "
|
85
|
+
stub_request(:get, "https://id.loc.gov/search/?format=json&q=Berry&q=cs:http://id.loc.gov/authorities/names")
|
86
86
|
.with(headers: { 'Accept' => 'application/json' })
|
87
87
|
.to_return(body: webmock_fixture("loc-names-response.txt"), status: 200)
|
88
88
|
end
|
@@ -188,7 +188,7 @@ describe Qa::TermsController, type: :controller do
|
|
188
188
|
describe "#show" do
|
189
189
|
context "with supported authorities" do
|
190
190
|
before do
|
191
|
-
stub_request(:get, "
|
191
|
+
stub_request(:get, "https://id.loc.gov/authorities/subjects/sh85077565.json")
|
192
192
|
.with(headers: { 'Accept' => 'application/json' })
|
193
193
|
.to_return(status: 200, body: webmock_fixture("loc-names-response.txt"), headers: {})
|
194
194
|
end
|
@@ -7,6 +7,34 @@ describe Qa::Authorities::Geonames do
|
|
7
7
|
|
8
8
|
let(:authority) { described_class.new }
|
9
9
|
|
10
|
+
describe ".query_url_host" do
|
11
|
+
subject { described_class.query_url_host }
|
12
|
+
it { is_expected.to eq "http://api.geonames.org" }
|
13
|
+
it "can be overridden" do
|
14
|
+
begin
|
15
|
+
before_change = described_class.query_url_host
|
16
|
+
described_class.query_url_host = "http://myhost.com"
|
17
|
+
expect(described_class.query_url_host).to eq("http://myhost.com")
|
18
|
+
ensure
|
19
|
+
described_class.query_url_host = before_change
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe ".find_url_host" do
|
25
|
+
subject { described_class.find_url_host }
|
26
|
+
it { is_expected.to eq "http://www.geonames.org" }
|
27
|
+
it "can be overridden" do
|
28
|
+
begin
|
29
|
+
before_change = described_class.find_url_host
|
30
|
+
described_class.find_url_host = "http://myhost.com"
|
31
|
+
expect(described_class.find_url_host).to eq("http://myhost.com")
|
32
|
+
ensure
|
33
|
+
described_class.find_url_host = before_change
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
10
38
|
describe "#build_query_url" do
|
11
39
|
subject { authority.build_query_url("foo") }
|
12
40
|
it { is_expected.to eq 'http://api.geonames.org/searchJSON?q=foo&username=dummy&maxRows=10' }
|
@@ -28,9 +56,9 @@ describe Qa::Authorities::Geonames do
|
|
28
56
|
|
29
57
|
context "with default label" do
|
30
58
|
it "has id and label keys" do
|
31
|
-
expect(subject.first).to eq("id" => '
|
59
|
+
expect(subject.first).to eq("id" => 'https://sws.geonames.org/2088122/',
|
32
60
|
"label" => "Port Moresby, National Capital, Papua New Guinea")
|
33
|
-
expect(subject.last).to eq("id" => '
|
61
|
+
expect(subject.last).to eq("id" => 'https://sws.geonames.org/377039/',
|
34
62
|
"label" => "Port Sudan, Red Sea, Sudan")
|
35
63
|
expect(subject.size).to eq(10)
|
36
64
|
end
|
@@ -77,7 +77,7 @@ describe Qa::Authorities::Getty::AAT do
|
|
77
77
|
subject { authority.request_options }
|
78
78
|
it { is_expected.to eq(accept: "application/sparql-results+json") }
|
79
79
|
end
|
80
|
-
# rubocop:disable
|
80
|
+
# rubocop:disable Layout/LineLength
|
81
81
|
describe "#sparql" do
|
82
82
|
context "using a single subject term" do
|
83
83
|
subject { authority.sparql('search_term') }
|
@@ -92,5 +92,5 @@ describe Qa::Authorities::Getty::AAT do
|
|
92
92
|
}
|
93
93
|
end
|
94
94
|
end
|
95
|
-
# rubocop:enable
|
95
|
+
# rubocop:enable Layout/LineLength
|
96
96
|
end
|
@@ -77,7 +77,7 @@ describe Qa::Authorities::Getty::TGN do
|
|
77
77
|
subject { authority.request_options }
|
78
78
|
it { is_expected.to eq(accept: "application/sparql-results+json") }
|
79
79
|
end
|
80
|
-
# rubocop:disable
|
80
|
+
# rubocop:disable Layout/LineLength
|
81
81
|
describe "#sparql" do
|
82
82
|
context "using a single subject term" do
|
83
83
|
subject { authority.sparql('search_term') }
|
@@ -92,5 +92,5 @@ describe Qa::Authorities::Getty::TGN do
|
|
92
92
|
}
|
93
93
|
end
|
94
94
|
end
|
95
|
-
# rubocop:enable
|
95
|
+
# rubocop:enable Layout/LineLength
|
96
96
|
end
|
@@ -8,18 +8,18 @@ RSpec.describe Qa::Authorities::LinkedData::FindTerm do
|
|
8
8
|
context 'basic parameter testing' do
|
9
9
|
context 'with bad id' do
|
10
10
|
before do
|
11
|
-
stub_request(:get, 'http://id.worldcat.org/fast/FAKE_ID')
|
11
|
+
stub_request(:get, 'http://id.worldcat.org/fast/FAKE_ID.rdf.xml')
|
12
12
|
.to_return(status: 404, body: '', headers: {})
|
13
13
|
end
|
14
14
|
it 'raises a TermNotFound exception' do
|
15
|
-
expect { lod_oclc.find('FAKE_ID') }.to raise_error Qa::TermNotFound, /.*\/FAKE_ID\ Not Found - Term may not exist at LOD Authority./
|
15
|
+
expect { lod_oclc.find('FAKE_ID') }.to raise_error Qa::TermNotFound, /.*\/FAKE_ID.rdf.xml\ Not Found - Term may not exist at LOD Authority./
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
20
|
context 'performance stats' do
|
21
21
|
before do
|
22
|
-
stub_request(:get, 'http://id.worldcat.org/fast/530369')
|
22
|
+
stub_request(:get, 'http://id.worldcat.org/fast/530369.rdf.xml')
|
23
23
|
.to_return(status: 200, body: webmock_fixture('lod_oclc_term_found.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
|
24
24
|
end
|
25
25
|
context 'when set to true' do
|
@@ -55,7 +55,7 @@ RSpec.describe Qa::Authorities::LinkedData::FindTerm do
|
|
55
55
|
|
56
56
|
context 'response header' do
|
57
57
|
before do
|
58
|
-
stub_request(:get, 'http://id.worldcat.org/fast/530369')
|
58
|
+
stub_request(:get, 'http://id.worldcat.org/fast/530369.rdf.xml')
|
59
59
|
.to_return(status: 200, body: webmock_fixture('lod_oclc_term_found.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
|
60
60
|
end
|
61
61
|
context 'when set to true' do
|
@@ -91,7 +91,7 @@ RSpec.describe Qa::Authorities::LinkedData::FindTerm do
|
|
91
91
|
context 'in OCLC_FAST authority' do
|
92
92
|
context 'term found' do
|
93
93
|
let :results do
|
94
|
-
stub_request(:get, 'http://id.worldcat.org/fast/530369')
|
94
|
+
stub_request(:get, 'http://id.worldcat.org/fast/530369.rdf.xml')
|
95
95
|
.to_return(status: 200, body: webmock_fixture('lod_oclc_term_found.rdf.xml'), headers: { 'Content-Type' => 'application/rdf+xml' })
|
96
96
|
lod_oclc.find('530369')
|
97
97
|
end
|
@@ -128,7 +128,7 @@ RSpec.describe Qa::Authorities::LinkedData::FindTerm do
|
|
128
128
|
|
129
129
|
context "ID in graph doesn't match ID in request URI" do
|
130
130
|
before do
|
131
|
-
stub_request(:get, 'http://id.worldcat.org/fast/530369')
|
131
|
+
stub_request(:get, 'http://id.worldcat.org/fast/530369.rdf.xml')
|
132
132
|
.to_return(status: 200, body: webmock_fixture('lod_oclc_term_bad_id.nt'), headers: { 'Content-Type' => 'application/ntriples' })
|
133
133
|
end
|
134
134
|
|
@@ -28,14 +28,14 @@ describe Qa::Authorities::Loc do
|
|
28
28
|
end
|
29
29
|
|
30
30
|
context "for searching" do
|
31
|
-
let(:url) { '
|
31
|
+
let(:url) { 'https://id.loc.gov/search/?q=foo&q=cs%3Ahttp%3A%2F%2Fid.loc.gov%2Fauthorities%2Fsubjects&format=json' }
|
32
32
|
it "returns a url" do
|
33
33
|
expect(authority.build_query_url("foo")).to eq(url)
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
37
|
context "for returning single terms" do
|
38
|
-
let(:url) { "
|
38
|
+
let(:url) { "https://id.loc.gov/authorities/subjects/sh2002003586.json" }
|
39
39
|
it "returns a url with an authority and id" do
|
40
40
|
expect(authority.find_url("sh2002003586")).to eq(url)
|
41
41
|
end
|
@@ -49,15 +49,15 @@ describe Qa::Authorities::Loc do
|
|
49
49
|
end
|
50
50
|
|
51
51
|
before do
|
52
|
-
stub_request(:get, "
|
52
|
+
stub_request(:get, "https://id.loc.gov/search/?format=json&q=cs:http://id.loc.gov/authorities/subjects")
|
53
53
|
.with(headers: { 'Accept' => 'application/json' })
|
54
54
|
.to_return(status: 200, body: "")
|
55
55
|
end
|
56
56
|
|
57
57
|
context "with flat params encoded" do
|
58
|
-
let(:url) { '
|
58
|
+
let(:url) { 'https://id.loc.gov/search/?q=foo&q=cs%3Ahttp%3A%2F%2Fid.loc.gov%2Fauthorities%2Fsubjects&format=json' }
|
59
59
|
it "returns a response" do
|
60
|
-
flat_params_url = "
|
60
|
+
flat_params_url = "https://id.loc.gov/search/?format=json&q=foo&q=cs%3Ahttp%3A%2F%2Fid.loc.gov%2Fauthorities%2Fsubjects"
|
61
61
|
expect(subject.env.url.to_s).to eq(flat_params_url)
|
62
62
|
end
|
63
63
|
end
|
@@ -66,7 +66,7 @@ describe Qa::Authorities::Loc do
|
|
66
66
|
describe "#search" do
|
67
67
|
context "any LOC authorities" do
|
68
68
|
let :authority do
|
69
|
-
stub_request(:get, "
|
69
|
+
stub_request(:get, "https://id.loc.gov/search/?format=json&q=s&q=cs:http://id.loc.gov/vocabulary/geographicAreas")
|
70
70
|
.with(headers: { 'Accept' => 'application/json' })
|
71
71
|
.to_return(body: webmock_fixture("loc-response.txt"), status: 200)
|
72
72
|
described_class.subauthority_for("geographicAreas")
|
@@ -95,7 +95,7 @@ describe Qa::Authorities::Loc do
|
|
95
95
|
|
96
96
|
context "subject terms" do
|
97
97
|
let :results do
|
98
|
-
stub_request(:get, "
|
98
|
+
stub_request(:get, "https://id.loc.gov/search/?format=json&q=History--&q=cs:http://id.loc.gov/authorities/subjects")
|
99
99
|
.with(headers: { 'Accept' => 'application/json' })
|
100
100
|
.to_return(body: webmock_fixture("loc-subjects-response.txt"), status: 200)
|
101
101
|
described_class.subauthority_for("subjects").search("History--")
|
@@ -111,7 +111,7 @@ describe Qa::Authorities::Loc do
|
|
111
111
|
|
112
112
|
context "name terms" do
|
113
113
|
let :results do
|
114
|
-
stub_request(:get, "
|
114
|
+
stub_request(:get, "https://id.loc.gov/search/?format=json&q=Berry&q=cs:http://id.loc.gov/authorities/names")
|
115
115
|
.with(headers: { 'Accept' => 'application/json' })
|
116
116
|
.to_return(body: webmock_fixture("loc-names-response.txt"), status: 200)
|
117
117
|
described_class.subauthority_for("names").search("Berry")
|
@@ -125,7 +125,7 @@ describe Qa::Authorities::Loc do
|
|
125
125
|
describe "#find" do
|
126
126
|
context "using a subject id" do
|
127
127
|
let :results do
|
128
|
-
stub_request(:get, "
|
128
|
+
stub_request(:get, "https://id.loc.gov/authorities/subjects/sh2002003586.json")
|
129
129
|
.with(headers: { 'Accept' => 'application/json' })
|
130
130
|
.to_return(status: 200, body: webmock_fixture("loc-subject-find-response.txt"), headers: {})
|
131
131
|
described_class.subauthority_for("subjects").find("sh2002003586")
|
@@ -47,7 +47,7 @@ EOS
|
|
47
47
|
expect(records[1]).to eq({})
|
48
48
|
end
|
49
49
|
|
50
|
-
# rubocop:disable
|
50
|
+
# rubocop:disable Layout/LineLength
|
51
51
|
it 'parses a sample mesh file' do
|
52
52
|
mesh = described_class.new(webmock_fixture('mesh.txt'))
|
53
53
|
records = mesh.all_records
|
@@ -117,5 +117,5 @@ EOS
|
|
117
117
|
"DX" => ["19840101"],
|
118
118
|
"UI" => ["D000001"])
|
119
119
|
end
|
120
|
-
# rubocop:enable
|
120
|
+
# rubocop:enable Layout/LineLength
|
121
121
|
end
|
@@ -83,16 +83,22 @@ RSpec.describe Qa::LinkedData::AuthorityUrlService do
|
|
83
83
|
let(:action_request) { 'mark twain' }
|
84
84
|
|
85
85
|
it 'returns template with substitutions' do
|
86
|
-
expected_url = 'http://experimental.worldcat.org/fast/search?query=oclc.personalName+all+%22mark
|
86
|
+
expected_url = 'http://experimental.worldcat.org/fast/search?query=oclc.personalName+all+%22mark%20twain%22&sortKeys=usage&maximumRecords=10'
|
87
87
|
expect(subject).to eq expected_url
|
88
88
|
end
|
89
|
+
|
90
|
+
it 'does not mutate substitutions hash' do
|
91
|
+
before_substitutions = substitutions.clone
|
92
|
+
subject
|
93
|
+
expect(substitutions).to eq before_substitutions
|
94
|
+
end
|
89
95
|
end
|
90
96
|
|
91
97
|
context 'when no substitutions specified' do
|
92
98
|
let(:action_request) { 'mark twain' }
|
93
99
|
|
94
100
|
it 'returns template with substitutions' do
|
95
|
-
expected_url = 'http://experimental.worldcat.org/fast/search?query=cql.any+all+%22mark
|
101
|
+
expected_url = 'http://experimental.worldcat.org/fast/search?query=cql.any+all+%22mark%20twain%22&sortKeys=usage&maximumRecords=20'
|
96
102
|
expect(subject).to eq expected_url
|
97
103
|
end
|
98
104
|
end
|
@@ -104,7 +110,7 @@ RSpec.describe Qa::LinkedData::AuthorityUrlService do
|
|
104
110
|
let(:action_request) { 'n79021164' }
|
105
111
|
|
106
112
|
it 'returns template with substitutions' do
|
107
|
-
expected_url = 'http://id.worldcat.org/fast/n79021164'
|
113
|
+
expected_url = 'http://id.worldcat.org/fast/n79021164.rdf.xml'
|
108
114
|
expect(subject).to eq expected_url
|
109
115
|
end
|
110
116
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: qa
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.5.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen Anderson
|
@@ -13,10 +13,10 @@ authors:
|
|
13
13
|
- Mike Stroming
|
14
14
|
- Adam Wead
|
15
15
|
- E. Lynette Rayle
|
16
|
-
autorequire:
|
16
|
+
autorequire:
|
17
17
|
bindir: bin
|
18
18
|
cert_chain: []
|
19
|
-
date:
|
19
|
+
date: 2020-12-02 00:00:00.000000000 Z
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
22
|
name: activerecord-import
|
@@ -142,14 +142,40 @@ dependencies:
|
|
142
142
|
requirements:
|
143
143
|
- - "~>"
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version:
|
145
|
+
version: 3.0.0
|
146
146
|
type: :development
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
150
|
- - "~>"
|
151
151
|
- !ruby/object:Gem::Version
|
152
|
-
version:
|
152
|
+
version: 3.0.0
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: rails
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "!="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: 5.2.0
|
160
|
+
- - "!="
|
161
|
+
- !ruby/object:Gem::Version
|
162
|
+
version: 5.2.1
|
163
|
+
- - "!="
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: 5.2.2
|
166
|
+
type: :development
|
167
|
+
prerelease: false
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
requirements:
|
170
|
+
- - "!="
|
171
|
+
- !ruby/object:Gem::Version
|
172
|
+
version: 5.2.0
|
173
|
+
- - "!="
|
174
|
+
- !ruby/object:Gem::Version
|
175
|
+
version: 5.2.1
|
176
|
+
- - "!="
|
177
|
+
- !ruby/object:Gem::Version
|
178
|
+
version: 5.2.2
|
153
179
|
- !ruby/object:Gem::Dependency
|
154
180
|
name: byebug
|
155
181
|
requirement: !ruby/object:Gem::Requirement
|
@@ -591,7 +617,7 @@ homepage: https://github.com/projecthydra/questioning_authority
|
|
591
617
|
licenses:
|
592
618
|
- APACHE-2
|
593
619
|
metadata: {}
|
594
|
-
post_install_message:
|
620
|
+
post_install_message:
|
595
621
|
rdoc_options: []
|
596
622
|
require_paths:
|
597
623
|
- lib
|
@@ -606,9 +632,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
606
632
|
- !ruby/object:Gem::Version
|
607
633
|
version: '0'
|
608
634
|
requirements: []
|
609
|
-
|
610
|
-
|
611
|
-
signing_key:
|
635
|
+
rubygems_version: 3.0.8
|
636
|
+
signing_key:
|
612
637
|
specification_version: 4
|
613
638
|
summary: You should question your authorities.
|
614
639
|
test_files:
|