federal_register 0.7.6 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +33 -6
- data/VERSION +1 -1
- data/federal_register.gemspec +8 -2
- data/lib/federal_register/agency.rb +4 -4
- data/lib/federal_register/base.rb +7 -1
- data/lib/federal_register/client.rb +39 -8
- data/lib/federal_register/document.rb +13 -26
- data/lib/federal_register/document_search_details.rb +1 -1
- data/lib/federal_register/document_utilities.rb +57 -0
- data/lib/federal_register/facet/agency.rb +1 -1
- data/lib/federal_register/facet/document/agency.rb +1 -1
- data/lib/federal_register/facet/document/daily.rb +1 -1
- data/lib/federal_register/facet/document/monthly.rb +1 -1
- data/lib/federal_register/facet/document/quarterly.rb +1 -1
- data/lib/federal_register/facet/document/section.rb +1 -1
- data/lib/federal_register/facet/document/topic.rb +1 -1
- data/lib/federal_register/facet/document/type.rb +1 -1
- data/lib/federal_register/facet/document/weekly.rb +1 -1
- data/lib/federal_register/facet/document/yearly.rb +1 -1
- data/lib/federal_register/facet/presidential_document_type.rb +1 -1
- data/lib/federal_register/facet/public_inspection_document/agencies.rb +1 -1
- data/lib/federal_register/facet/public_inspection_document/agency.rb +1 -1
- data/lib/federal_register/facet/public_inspection_document/type.rb +1 -1
- data/lib/federal_register/facet/public_inspection_issue/daily.rb +1 -1
- data/lib/federal_register/facet/public_inspection_issue/type.rb +1 -1
- data/lib/federal_register/facet/topic.rb +1 -1
- data/lib/federal_register/public_inspection_document.rb +8 -20
- data/lib/federal_register/public_inspection_document_search_details.rb +2 -2
- data/lib/federal_register/result_set.rb +2 -1
- data/lib/federal_register/section.rb +1 -1
- data/lib/federal_register/suggested_search.rb +2 -2
- data/lib/federal_register/topic.rb +1 -1
- data/lib/federal_register.rb +2 -1
- data/spec/agency_spec.rb +10 -1
- data/spec/base_spec.rb +2 -2
- data/spec/document_spec.rb +147 -32
- data/spec/public_inspection_document_spec.rb +35 -21
- data/spec/result_set_spec.rb +10 -1
- data/spec/spec_helper.rb +2 -4
- metadata +48 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9fa85057a2a29eaca05e6e24cbab933a2cb5da88eaae7e9e2a2bb99d94aea521
|
|
4
|
+
data.tar.gz: aba8ed95d1962cd872556da2f51b2a9024f8c9b430223a2d46779690dd943269
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 216eeb36c4e2f5e55ba14e83bc019d30b12e65551aad4b5b8a6064e7d3cc10ff06b481f403296cbdf9e1c0849edc56c98352f96af22b0b67b098e754a4438fc4
|
|
7
|
+
data.tar.gz: 01bc4a1455537a710ceb0572cda84b57c834574b3e1cc62e7b70785fa042729ac9b7a69b06801fdb7f4709ba43965ab7d01b01d84d5724124c5974ce2f137455
|
data/Gemfile.lock
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
federal_register (0.
|
|
5
|
-
|
|
4
|
+
federal_register (0.7.7)
|
|
5
|
+
faraday (>= 1.8)
|
|
6
6
|
|
|
7
7
|
GEM
|
|
8
8
|
remote: https://rubygems.org/
|
|
@@ -10,23 +10,40 @@ GEM
|
|
|
10
10
|
activesupport (3.2.22.5)
|
|
11
11
|
i18n (~> 0.6, >= 0.6.4)
|
|
12
12
|
multi_json (~> 1.0)
|
|
13
|
+
addressable (2.8.7)
|
|
14
|
+
public_suffix (>= 2.0.2, < 7.0)
|
|
13
15
|
ast (2.3.0)
|
|
16
|
+
base64 (0.2.0)
|
|
17
|
+
bigdecimal (3.1.8)
|
|
18
|
+
coderay (1.1.3)
|
|
14
19
|
concurrent-ruby (1.0.5)
|
|
20
|
+
crack (1.0.0)
|
|
21
|
+
bigdecimal
|
|
22
|
+
rexml
|
|
15
23
|
diff-lcs (1.2.5)
|
|
16
24
|
fakeweb (1.3.0)
|
|
17
|
-
|
|
18
|
-
|
|
25
|
+
faraday (2.8.1)
|
|
26
|
+
base64
|
|
27
|
+
faraday-net_http (>= 2.0, < 3.1)
|
|
28
|
+
ruby2_keywords (>= 0.0.4)
|
|
29
|
+
faraday-net_http (3.0.2)
|
|
30
|
+
hashdiff (1.1.1)
|
|
19
31
|
i18n (0.9.1)
|
|
20
32
|
concurrent-ruby (~> 1.0)
|
|
33
|
+
method_source (1.1.0)
|
|
21
34
|
multi_json (1.12.2)
|
|
22
|
-
multi_xml (0.6.0)
|
|
23
35
|
parallel (1.12.0)
|
|
24
36
|
parser (2.4.0.2)
|
|
25
37
|
ast (~> 2.3)
|
|
26
38
|
powerpack (0.1.1)
|
|
39
|
+
pry (0.14.2)
|
|
40
|
+
coderay (~> 1.1)
|
|
41
|
+
method_source (~> 1.0)
|
|
42
|
+
public_suffix (5.1.1)
|
|
27
43
|
rainbow (2.2.2)
|
|
28
44
|
rake
|
|
29
45
|
rake (12.3.0)
|
|
46
|
+
rexml (3.3.8)
|
|
30
47
|
rspec (2.99.0)
|
|
31
48
|
rspec-core (~> 2.99.0)
|
|
32
49
|
rspec-expectations (~> 2.99.0)
|
|
@@ -35,6 +52,8 @@ GEM
|
|
|
35
52
|
rspec-expectations (2.99.2)
|
|
36
53
|
diff-lcs (>= 1.1.3, < 2.0)
|
|
37
54
|
rspec-mocks (2.99.3)
|
|
55
|
+
rspec_junit_formatter (0.4.1)
|
|
56
|
+
rspec-core (>= 2, < 4, != 2.12.0)
|
|
38
57
|
rubocop (0.51.0)
|
|
39
58
|
parallel (~> 1.10)
|
|
40
59
|
parser (>= 2.3.3.1, < 3.0)
|
|
@@ -43,6 +62,7 @@ GEM
|
|
|
43
62
|
ruby-progressbar (~> 1.7)
|
|
44
63
|
unicode-display_width (~> 1.0, >= 1.0.1)
|
|
45
64
|
ruby-progressbar (1.9.0)
|
|
65
|
+
ruby2_keywords (0.0.5)
|
|
46
66
|
shoulda (3.5.0)
|
|
47
67
|
shoulda-context (~> 1.0, >= 1.0.1)
|
|
48
68
|
shoulda-matchers (>= 1.4.1, < 3.0)
|
|
@@ -50,6 +70,10 @@ GEM
|
|
|
50
70
|
shoulda-matchers (2.7.0)
|
|
51
71
|
activesupport (>= 3.0.0)
|
|
52
72
|
unicode-display_width (1.3.0)
|
|
73
|
+
webmock (3.24.0)
|
|
74
|
+
addressable (>= 2.8.0)
|
|
75
|
+
crack (>= 0.3.2)
|
|
76
|
+
hashdiff (>= 0.4.0, < 2.0.0)
|
|
53
77
|
|
|
54
78
|
PLATFORMS
|
|
55
79
|
ruby
|
|
@@ -59,9 +83,12 @@ DEPENDENCIES
|
|
|
59
83
|
bundler
|
|
60
84
|
fakeweb (~> 1.3.0)
|
|
61
85
|
federal_register!
|
|
86
|
+
pry
|
|
62
87
|
rspec (~> 2.6)
|
|
88
|
+
rspec_junit_formatter
|
|
63
89
|
rubocop
|
|
64
90
|
shoulda
|
|
91
|
+
webmock
|
|
65
92
|
|
|
66
93
|
BUNDLED WITH
|
|
67
|
-
|
|
94
|
+
2.3.6
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.8.0
|
data/federal_register.gemspec
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
Gem::Specification.new do |s|
|
|
7
7
|
s.name = "federal_register"
|
|
8
|
-
s.version = "0.
|
|
8
|
+
s.version = "0.8.0"
|
|
9
9
|
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
11
11
|
s.authors = ["Andrew Carpenter", "Bob Burbach"]
|
|
@@ -35,6 +35,7 @@ Gem::Specification.new do |s|
|
|
|
35
35
|
"lib/federal_register/document.rb",
|
|
36
36
|
"lib/federal_register/document_image.rb",
|
|
37
37
|
"lib/federal_register/document_search_details.rb",
|
|
38
|
+
"lib/federal_register/document_utilities.rb",
|
|
38
39
|
"lib/federal_register/facet.rb",
|
|
39
40
|
"lib/federal_register/facet/agency.rb",
|
|
40
41
|
"lib/federal_register/facet/document.rb",
|
|
@@ -86,14 +87,17 @@ Gem::Specification.new do |s|
|
|
|
86
87
|
s.specification_version = 3
|
|
87
88
|
|
|
88
89
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
|
89
|
-
s.add_runtime_dependency(%q<
|
|
90
|
+
s.add_runtime_dependency(%q<faraday>, [">= 1.8"])
|
|
90
91
|
|
|
91
92
|
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
|
92
93
|
s.add_development_dependency(%q<bundler>, [">= 0"])
|
|
93
94
|
s.add_development_dependency(%q<rspec>, ["~> 2.6"])
|
|
94
95
|
s.add_development_dependency(%q<activesupport>, ["~> 3"])
|
|
95
96
|
s.add_development_dependency(%q<fakeweb>, ["~> 1.3.0"])
|
|
97
|
+
s.add_development_dependency(%q<webmock>, [">= 0"])
|
|
96
98
|
s.add_development_dependency(%q<rubocop>, [">= 0"])
|
|
99
|
+
s.add_development_dependency(%q<rspec_junit_formatter>, [">= 0"])
|
|
100
|
+
s.add_development_dependency(%q<pry>, [">= 0"])
|
|
97
101
|
else
|
|
98
102
|
s.add_dependency(%q<httparty>, [">= 0.7.0"])
|
|
99
103
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
|
@@ -102,6 +106,7 @@ Gem::Specification.new do |s|
|
|
|
102
106
|
s.add_dependency(%q<activesupport>, ["~> 3"])
|
|
103
107
|
s.add_dependency(%q<fakeweb>, ["~> 1.3.0"])
|
|
104
108
|
s.add_dependency(%q<rubocop>, [">= 0"])
|
|
109
|
+
s.add_dependency(%q<rspec_junit_formatter>, [">= 0"])
|
|
105
110
|
end
|
|
106
111
|
else
|
|
107
112
|
s.add_dependency(%q<httparty>, [">= 0.14.0"])
|
|
@@ -111,5 +116,6 @@ Gem::Specification.new do |s|
|
|
|
111
116
|
s.add_dependency(%q<activesupport>, ["~> 3"])
|
|
112
117
|
s.add_dependency(%q<fakeweb>, ["~> 1.3.0"])
|
|
113
118
|
s.add_dependency(%q<rubocop>, [">= 0"])
|
|
119
|
+
s.add_dependency(%q<rspec_junit_formatter>, [">= 0"])
|
|
114
120
|
end
|
|
115
121
|
end
|
|
@@ -18,7 +18,7 @@ class FederalRegister::Agency < FederalRegister::Base
|
|
|
18
18
|
get_options = {}
|
|
19
19
|
get_options.merge!(:query => {:fields => options[:fields]}) if options[:fields]
|
|
20
20
|
|
|
21
|
-
response = get('
|
|
21
|
+
response = get('agencies.json', get_options).parsed_response
|
|
22
22
|
|
|
23
23
|
response.map do |hsh|
|
|
24
24
|
new(hsh, :full => true)
|
|
@@ -29,7 +29,7 @@ class FederalRegister::Agency < FederalRegister::Base
|
|
|
29
29
|
slug = URI.encode(id_or_slug.to_s)
|
|
30
30
|
|
|
31
31
|
if options[:fields].present?
|
|
32
|
-
response = get("
|
|
32
|
+
response = get("agencies/#{slug}.json", :query => {:fields => options[:fields]}).parsed_response
|
|
33
33
|
|
|
34
34
|
if response.is_a?(Hash)
|
|
35
35
|
new(response)
|
|
@@ -39,7 +39,7 @@ class FederalRegister::Agency < FederalRegister::Base
|
|
|
39
39
|
end
|
|
40
40
|
end
|
|
41
41
|
else
|
|
42
|
-
response = get("
|
|
42
|
+
response = get("agencies/#{slug}.json").parsed_response
|
|
43
43
|
|
|
44
44
|
if response.is_a?(Hash)
|
|
45
45
|
new(response, :full => true)
|
|
@@ -52,7 +52,7 @@ class FederalRegister::Agency < FederalRegister::Base
|
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
def self.suggestions(args={})
|
|
55
|
-
response = get("
|
|
55
|
+
response = get("agencies/suggestions", query: args).parsed_response
|
|
56
56
|
|
|
57
57
|
response.map do |hsh|
|
|
58
58
|
new(hsh, :full => true)
|
|
@@ -103,7 +103,13 @@ class FederalRegister::Base < FederalRegister::Client
|
|
|
103
103
|
FederalRegister::PublicInspectionIssueResultSet,
|
|
104
104
|
FederalRegister::FacetResultSet,
|
|
105
105
|
].each do |klass|
|
|
106
|
-
|
|
106
|
+
|
|
107
|
+
klass.class_eval do
|
|
108
|
+
define_singleton_method(:base_uri) do
|
|
109
|
+
uri
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
107
113
|
end
|
|
108
114
|
end
|
|
109
115
|
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
class FederalRegister::Client
|
|
2
|
-
include HTTParty
|
|
3
2
|
|
|
4
|
-
class ResponseError <
|
|
3
|
+
class ResponseError < Faraday::Error
|
|
4
|
+
|
|
5
|
+
attr_reader :response
|
|
6
|
+
|
|
7
|
+
def initialize(response)
|
|
8
|
+
@response = response
|
|
9
|
+
super(message)
|
|
10
|
+
end
|
|
11
|
+
|
|
5
12
|
def message
|
|
6
13
|
response.body
|
|
7
14
|
end
|
|
@@ -17,14 +24,26 @@ class FederalRegister::Client
|
|
|
17
24
|
class ServerError < ResponseError; end
|
|
18
25
|
class ServiceUnavailable < ResponseError; end
|
|
19
26
|
|
|
20
|
-
|
|
27
|
+
FaradayResponseWrapper = Struct.new(:parsed_response)
|
|
28
|
+
|
|
29
|
+
def self.base_uri
|
|
30
|
+
'https://www.federalregister.gov/api/v1'
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.get(path, options={})
|
|
34
|
+
@connection = Faraday.new(url: base_uri) do |conn|
|
|
35
|
+
conn.request :url_encoded
|
|
36
|
+
conn.response :logger if ENV['DEBUG'] # Optional: Enable logging in debug mode
|
|
37
|
+
conn.adapter Faraday.default_adapter
|
|
38
|
+
conn.options.open_timeout = ENV['FARADAY_OPEN_TIMEOUT'].try(:to_i) || 2
|
|
39
|
+
conn.options.timeout = 10
|
|
40
|
+
end
|
|
21
41
|
|
|
22
|
-
|
|
23
|
-
response = super
|
|
42
|
+
response = @connection.get(strip_protocol_and_host(path), options[:query] || {})
|
|
24
43
|
|
|
25
|
-
case response.
|
|
44
|
+
case response.status
|
|
26
45
|
when 200
|
|
27
|
-
response
|
|
46
|
+
FaradayResponseWrapper.new(JSON.parse(response.body))
|
|
28
47
|
when 400
|
|
29
48
|
raise BadRequest.new(response)
|
|
30
49
|
when 404
|
|
@@ -36,7 +55,19 @@ class FederalRegister::Client
|
|
|
36
55
|
when 504
|
|
37
56
|
raise GatewayTimeout.new(response)
|
|
38
57
|
else
|
|
39
|
-
raise
|
|
58
|
+
raise Faraday::Error.new(nil, response)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def self.strip_protocol_and_host(path)
|
|
63
|
+
uri = URI.parse(path)
|
|
64
|
+
|
|
65
|
+
path_without_protocol_and_host = uri.path
|
|
66
|
+
if uri.query
|
|
67
|
+
path_without_protocol_and_host << "?#{uri.query}"
|
|
40
68
|
end
|
|
69
|
+
|
|
70
|
+
path_without_protocol_and_host
|
|
41
71
|
end
|
|
72
|
+
private_class_method :strip_protocol_and_host
|
|
42
73
|
end
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
class FederalRegister::Document < FederalRegister::Base
|
|
2
2
|
extend FederalRegister::Utilities
|
|
3
|
+
extend FederalRegister::DocumentUtilities
|
|
3
4
|
|
|
4
5
|
add_attribute :abstract,
|
|
5
6
|
:abstract_html_url,
|
|
@@ -52,11 +53,11 @@ class FederalRegister::Document < FederalRegister::Base
|
|
|
52
53
|
:type => :date
|
|
53
54
|
|
|
54
55
|
def self.search(args)
|
|
55
|
-
FederalRegister::ResultSet.fetch("
|
|
56
|
+
FederalRegister::ResultSet.fetch("documents.json", :query => args, :result_class => self)
|
|
56
57
|
end
|
|
57
58
|
|
|
58
59
|
def self.search_metadata(args)
|
|
59
|
-
FederalRegister::ResultSet.fetch("
|
|
60
|
+
FederalRegister::ResultSet.fetch("documents.json", :query => args.merge(:metadata_only => '1'), :result_class => self)
|
|
60
61
|
end
|
|
61
62
|
|
|
62
63
|
def self.find(document_number, options={})
|
|
@@ -64,7 +65,7 @@ class FederalRegister::Document < FederalRegister::Base
|
|
|
64
65
|
|
|
65
66
|
if options[:publication_date].present?
|
|
66
67
|
publication_date = options[:publication_date]
|
|
67
|
-
publication_date = publication_date.is_a?(Date) ? publication_date.
|
|
68
|
+
publication_date = publication_date.is_a?(Date) ? publication_date.strftime("%Y-%m-%d") : publication_date
|
|
68
69
|
|
|
69
70
|
query.merge!(:publication_date => publication_date)
|
|
70
71
|
end
|
|
@@ -73,27 +74,12 @@ class FederalRegister::Document < FederalRegister::Base
|
|
|
73
74
|
query.merge!(:fields => options[:fields])
|
|
74
75
|
end
|
|
75
76
|
|
|
76
|
-
attributes = get("
|
|
77
|
+
attributes = get("documents/#{document_number}.json", :query => query).parsed_response
|
|
77
78
|
new(attributes, :full => true)
|
|
78
79
|
end
|
|
79
80
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
def self.find_all(*args)
|
|
83
|
-
options, document_numbers_or_citations = extract_options(args)
|
|
84
|
-
document_numbers_or_citations.flatten!
|
|
85
|
-
|
|
86
|
-
fetch_options = {:result_class => self}
|
|
87
|
-
fetch_options.merge!(:query => {:fields => options[:fields]}) if options[:fields]
|
|
88
|
-
|
|
89
|
-
#TODO: fix this gross hack to ensure that find_all with a single document number
|
|
90
|
-
# is returned in the same way multiple document numbers are
|
|
91
|
-
if document_numbers_or_citations.size == 1
|
|
92
|
-
document_numbers_or_citations << " "
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
params = URI.encode(document_numbers_or_citations.compact.join(',').strip)
|
|
96
|
-
result_set = FederalRegister::ResultSet.fetch("/documents/#{params}.json", fetch_options)
|
|
81
|
+
def self.find_all_base_path
|
|
82
|
+
'documents'
|
|
97
83
|
end
|
|
98
84
|
|
|
99
85
|
def agencies
|
|
@@ -104,13 +90,14 @@ class FederalRegister::Document < FederalRegister::Base
|
|
|
104
90
|
|
|
105
91
|
%w(full_text_xml abstract_html body_html raw_text mods).each do |file_type|
|
|
106
92
|
define_method file_type do
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
93
|
+
response = Faraday.get(send("#{file_type}_url"))
|
|
94
|
+
if response.success?
|
|
95
|
+
response.body
|
|
96
|
+
elsif response.status == 404
|
|
110
97
|
nil
|
|
111
|
-
|
|
98
|
+
else
|
|
112
99
|
raise send("#{file_type}_url").inspect
|
|
113
|
-
|
|
100
|
+
end
|
|
114
101
|
end
|
|
115
102
|
end
|
|
116
103
|
|
|
@@ -5,7 +5,7 @@ class FederalRegister::DocumentSearchDetails < FederalRegister::Base
|
|
|
5
5
|
:suggestions
|
|
6
6
|
|
|
7
7
|
def self.search(args)
|
|
8
|
-
response = get('
|
|
8
|
+
response = get('documents/search-details', query: args).parsed_response
|
|
9
9
|
new(response)
|
|
10
10
|
end
|
|
11
11
|
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
module FederalRegister::DocumentUtilities
|
|
2
|
+
URL_CHARACTER_LIMIT = 2000
|
|
3
|
+
|
|
4
|
+
def find_all(*args)
|
|
5
|
+
options, document_numbers_or_citations = extract_options(args)
|
|
6
|
+
document_numbers_or_citations.flatten!
|
|
7
|
+
|
|
8
|
+
fetch_options = {:result_class => self}
|
|
9
|
+
fetch_options.merge!(:query => {:fields => options[:fields]}) if options[:fields]
|
|
10
|
+
|
|
11
|
+
document_numbers_or_citations.uniq!
|
|
12
|
+
|
|
13
|
+
if document_numbers_or_citations.empty?
|
|
14
|
+
raise "No documents or citation numbers were provided"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
#TODO: fix this gross hack to ensure that find_all with a single document number
|
|
18
|
+
# is returned in the same way multiple document numbers are
|
|
19
|
+
if document_numbers_or_citations.size == 1
|
|
20
|
+
document_numbers_or_citations << " "
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
http_request_batches = calculate_request_batches(document_numbers_or_citations, fetch_options)
|
|
24
|
+
|
|
25
|
+
slice_size = (document_numbers_or_citations.count.to_f / http_request_batches).ceil
|
|
26
|
+
results = []
|
|
27
|
+
document_numbers_or_citations.each_slice(slice_size).each do |slice|
|
|
28
|
+
|
|
29
|
+
params = URI.encode(slice.join(',').strip)
|
|
30
|
+
url = "#{find_all_base_path}/#{params}.json"
|
|
31
|
+
response = get(url, fetch_options).parsed_response
|
|
32
|
+
results += response['results']
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
FederalRegister::ResultSet.new(
|
|
36
|
+
{
|
|
37
|
+
'count' => results.count,
|
|
38
|
+
'results' => results,
|
|
39
|
+
},
|
|
40
|
+
self
|
|
41
|
+
)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
def calculate_request_batches(document_numbers_or_citations, fetch_options)
|
|
47
|
+
fetch_option_url_character_count = URI.encode_www_form(fetch_options).length # HTTPParty uses Net::HTTP
|
|
48
|
+
characters_available = URL_CHARACTER_LIMIT - fetch_option_url_character_count
|
|
49
|
+
doc_number_character_count = URI.encode(document_numbers_or_citations.compact.join(',').strip).length
|
|
50
|
+
|
|
51
|
+
if characters_available > doc_number_character_count
|
|
52
|
+
1
|
|
53
|
+
else
|
|
54
|
+
(doc_number_character_count.to_f / characters_available).ceil
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
class FederalRegister::PublicInspectionDocument < FederalRegister::Base
|
|
2
2
|
extend FederalRegister::Utilities
|
|
3
|
+
extend FederalRegister::DocumentUtilities
|
|
3
4
|
|
|
4
5
|
add_attribute :agencies,
|
|
5
6
|
:docket_numbers,
|
|
@@ -23,41 +24,28 @@ class FederalRegister::PublicInspectionDocument < FederalRegister::Base
|
|
|
23
24
|
:type => :datetime
|
|
24
25
|
|
|
25
26
|
def self.search(args)
|
|
26
|
-
FederalRegister::ResultSet.fetch("
|
|
27
|
+
FederalRegister::ResultSet.fetch("public-inspection-documents.json", :query => args, :result_class => self)
|
|
27
28
|
end
|
|
28
29
|
|
|
29
30
|
def self.search_metadata(args)
|
|
30
|
-
FederalRegister::ResultSet.fetch("
|
|
31
|
+
FederalRegister::ResultSet.fetch("public-inspection-documents.json", :query => args.merge(:metadata_only => '1'), :result_class => self)
|
|
31
32
|
end
|
|
32
33
|
|
|
33
34
|
def self.find(document_number)
|
|
34
|
-
attributes = get("
|
|
35
|
+
attributes = get("public-inspection-documents/#{document_number}.json").parsed_response
|
|
35
36
|
new(attributes, :full => true)
|
|
36
37
|
end
|
|
37
38
|
|
|
38
39
|
def self.available_on(date)
|
|
39
|
-
FederalRegister::PublicInspectionIssueResultSet.fetch("
|
|
40
|
+
FederalRegister::PublicInspectionIssueResultSet.fetch("public-inspection-documents.json", :query => {:conditions => {:available_on => date}}, :result_class => self)
|
|
40
41
|
end
|
|
41
42
|
|
|
42
43
|
def self.current
|
|
43
|
-
FederalRegister::PublicInspectionIssueResultSet.fetch("
|
|
44
|
+
FederalRegister::PublicInspectionIssueResultSet.fetch("public-inspection-documents/current.json", :result_class => self)
|
|
44
45
|
end
|
|
45
46
|
|
|
46
|
-
def self.
|
|
47
|
-
|
|
48
|
-
document_numbers.flatten!
|
|
49
|
-
|
|
50
|
-
fetch_options = {:result_class => self}
|
|
51
|
-
fetch_options.merge!(:query => {:fields => options[:fields]}) if options[:fields]
|
|
52
|
-
|
|
53
|
-
#TODO: fix this gross hack to ensure that find_all with a single document number
|
|
54
|
-
# is returned in the same way multiple document numbers are
|
|
55
|
-
if document_numbers.size == 1
|
|
56
|
-
document_numbers << " "
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
params = URI.encode(document_numbers.compact.join(',').strip)
|
|
60
|
-
result_set = FederalRegister::ResultSet.fetch("/public-inspection-documents/#{params}.json", fetch_options)
|
|
47
|
+
def self.find_all_base_path
|
|
48
|
+
'public-inspection-documents'
|
|
61
49
|
end
|
|
62
50
|
|
|
63
51
|
def agencies
|
|
@@ -5,7 +5,7 @@ class FederalRegister::PublicInspectionDocumentSearchDetails < FederalRegister::
|
|
|
5
5
|
:suggestions
|
|
6
6
|
|
|
7
7
|
def self.search(args)
|
|
8
|
-
response = get('
|
|
8
|
+
response = get('public-inspection-documents/search-details', query: args).parsed_response
|
|
9
9
|
new(response)
|
|
10
10
|
end
|
|
11
|
-
end
|
|
11
|
+
end
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
class FederalRegister::ResultSet < FederalRegister::Client
|
|
2
2
|
include Enumerable
|
|
3
3
|
|
|
4
|
-
attr_reader :count, :total_pages, :results, :errors, :description
|
|
4
|
+
attr_reader :count, :total_pages, :results, :errors, :description, :is_neural
|
|
5
5
|
|
|
6
6
|
def initialize(attributes, result_class)
|
|
7
7
|
@result_class = result_class
|
|
8
8
|
@count = attributes['count']
|
|
9
|
+
@is_neural = attributes['is_neural']
|
|
9
10
|
@total_pages = attributes['total_pages']
|
|
10
11
|
@results = (attributes['results'] || []).map{|result| @result_class.new(result) }
|
|
11
12
|
|
|
@@ -2,7 +2,7 @@ class FederalRegister::Section < FederalRegister::Base
|
|
|
2
2
|
add_attribute :name
|
|
3
3
|
|
|
4
4
|
def self.search(args={})
|
|
5
|
-
response = get('
|
|
5
|
+
response = get('sections', query: args).parsed_response
|
|
6
6
|
|
|
7
7
|
responses = {}
|
|
8
8
|
response.map do |section, attributes|
|
|
@@ -9,7 +9,7 @@ class FederalRegister::SuggestedSearch < FederalRegister::Base
|
|
|
9
9
|
:title
|
|
10
10
|
|
|
11
11
|
def self.search(args={})
|
|
12
|
-
response = get('
|
|
12
|
+
response = get('suggested_searches', query: args).parsed_response
|
|
13
13
|
|
|
14
14
|
responses = {}
|
|
15
15
|
response.map do |section, searches|
|
|
@@ -20,7 +20,7 @@ class FederalRegister::SuggestedSearch < FederalRegister::Base
|
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def self.find(slug)
|
|
23
|
-
response = get("
|
|
23
|
+
response = get("suggested_searches/#{URI.encode(slug.to_s)}").parsed_response
|
|
24
24
|
new(response)
|
|
25
25
|
end
|
|
26
26
|
end
|
|
@@ -4,7 +4,7 @@ class FederalRegister::Topic < FederalRegister::Base
|
|
|
4
4
|
:url
|
|
5
5
|
|
|
6
6
|
def self.suggestions(args={})
|
|
7
|
-
response = get("
|
|
7
|
+
response = get("topics/suggestions", query: args).parsed_response
|
|
8
8
|
|
|
9
9
|
response.map do |hsh|
|
|
10
10
|
new(hsh, :full => true)
|
data/lib/federal_register.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
require 'rubygems'
|
|
2
|
-
require '
|
|
2
|
+
require 'faraday'
|
|
3
3
|
|
|
4
4
|
module FederalRegister
|
|
5
5
|
end
|
|
@@ -12,6 +12,7 @@ require "federal_register/result_set.rb"
|
|
|
12
12
|
require "federal_register/public_inspection_issue_result_set.rb"
|
|
13
13
|
require "federal_register/facet_result_set.rb"
|
|
14
14
|
|
|
15
|
+
require "federal_register/document_utilities.rb"
|
|
15
16
|
require "federal_register/agency.rb"
|
|
16
17
|
require "federal_register/document.rb"
|
|
17
18
|
require "federal_register/article.rb"
|
data/spec/agency_spec.rb
CHANGED
|
@@ -3,7 +3,16 @@ require File.dirname(__FILE__) + '/spec_helper'
|
|
|
3
3
|
describe FederalRegister::Agency do
|
|
4
4
|
describe ".all" do
|
|
5
5
|
before(:each) do
|
|
6
|
-
|
|
6
|
+
stub_request(
|
|
7
|
+
:get,
|
|
8
|
+
"https://www.federalregister.gov/api/v1/agencies.json"
|
|
9
|
+
)
|
|
10
|
+
.to_return(
|
|
11
|
+
body: [{},{}].to_json,
|
|
12
|
+
headers: { 'Content-Type' => 'application/json' },
|
|
13
|
+
status: 200
|
|
14
|
+
)
|
|
15
|
+
|
|
7
16
|
end
|
|
8
17
|
|
|
9
18
|
it "returns Agency objects" do
|
data/spec/base_spec.rb
CHANGED
|
@@ -101,8 +101,8 @@ describe FederalRegister::Base do
|
|
|
101
101
|
end
|
|
102
102
|
|
|
103
103
|
[FederalRegister::Agency, FederalRegister::Article, FederalRegister::Base, FederalRegister::Client, FederalRegister::ResultSet].each do |klass|
|
|
104
|
-
it "should set
|
|
105
|
-
klass.
|
|
104
|
+
it "should set base uri for #{klass}" do
|
|
105
|
+
klass.base_uri.should == 'http://fr2.local/api/v1'
|
|
106
106
|
end
|
|
107
107
|
end
|
|
108
108
|
|
data/spec/document_spec.rb
CHANGED
|
@@ -4,23 +4,30 @@ describe FederalRegister::Document do
|
|
|
4
4
|
describe ".find" do
|
|
5
5
|
it "fetches the document by its document number" do
|
|
6
6
|
document_number = "2010-213"
|
|
7
|
-
|
|
7
|
+
stub_request(
|
|
8
8
|
:get,
|
|
9
9
|
"https://www.federalregister.gov/api/v1/documents/#{document_number}.json",
|
|
10
|
-
:content_type =>"text/json",
|
|
11
|
-
:body => {:title => "Important Notice"}.to_json
|
|
12
10
|
)
|
|
11
|
+
.to_return(
|
|
12
|
+
body: {:title => "Important Notice"}.to_json,
|
|
13
|
+
headers: { 'Content-Type' => 'text/json' },
|
|
14
|
+
)
|
|
15
|
+
|
|
13
16
|
|
|
14
17
|
FederalRegister::Document.find(document_number).title.should == 'Important Notice'
|
|
15
18
|
end
|
|
16
19
|
|
|
17
20
|
it "fetches the document with only requested fields (when present)" do
|
|
18
21
|
document_number = "2010-213"
|
|
19
|
-
|
|
22
|
+
params = URI.encode_www_form([["fields[]","title"],["fields[]", "start_page"]])
|
|
23
|
+
|
|
24
|
+
stub_request(
|
|
20
25
|
:get,
|
|
21
|
-
"https://www.federalregister.gov/api/v1/documents/#{document_number}.json
|
|
22
|
-
|
|
23
|
-
|
|
26
|
+
"https://www.federalregister.gov/api/v1/documents/#{document_number}.json?#{params}",
|
|
27
|
+
)
|
|
28
|
+
.to_return(
|
|
29
|
+
body: {:title => "Important Notice", :start_page => 12345}.to_json,
|
|
30
|
+
headers: { 'Content-Type' => 'text/json' },
|
|
24
31
|
)
|
|
25
32
|
|
|
26
33
|
result = FederalRegister::Document.find(document_number, :fields => ["title", "start_page"])
|
|
@@ -32,12 +39,17 @@ describe FederalRegister::Document do
|
|
|
32
39
|
it "fetches the document with the provided publication date (when present)" do
|
|
33
40
|
document_number = "2010-213"
|
|
34
41
|
publication_date = "2010-02-02"
|
|
35
|
-
|
|
42
|
+
params = URI.encode_www_form([["publication_date", "#{publication_date}"]])
|
|
43
|
+
|
|
44
|
+
stub_request(
|
|
36
45
|
:get,
|
|
37
|
-
"https://www.federalregister.gov/api/v1/documents/#{document_number}.json
|
|
38
|
-
|
|
39
|
-
|
|
46
|
+
"https://www.federalregister.gov/api/v1/documents/#{document_number}.json?#{params}"
|
|
47
|
+
)
|
|
48
|
+
.to_return(
|
|
49
|
+
body: {:title => "Important Notice", :publication_date => publication_date}.to_json,
|
|
50
|
+
headers: { 'Content-Type' => 'text/json' }
|
|
40
51
|
)
|
|
52
|
+
|
|
41
53
|
|
|
42
54
|
result = FederalRegister::Document.find(document_number, :publication_date => publication_date)
|
|
43
55
|
result.title.should eql("Important Notice")
|
|
@@ -46,50 +58,148 @@ describe FederalRegister::Document do
|
|
|
46
58
|
|
|
47
59
|
it "throws an error when a document doesn't exist" do
|
|
48
60
|
document_number = "some-random-document"
|
|
49
|
-
|
|
61
|
+
stub_request(
|
|
50
62
|
:get,
|
|
51
63
|
"https://www.federalregister.gov/api/v1/documents/#{document_number}.json",
|
|
52
|
-
:content_type =>"text/json",
|
|
53
|
-
:status => 404
|
|
54
64
|
)
|
|
65
|
+
.to_return(
|
|
66
|
+
headers: { 'Content-Type' => 'text/json' },
|
|
67
|
+
status: 404
|
|
68
|
+
)
|
|
69
|
+
|
|
55
70
|
lambda{ FederalRegister::Document.find(document_number) }.should raise_error FederalRegister::Client::RecordNotFound
|
|
56
71
|
end
|
|
57
72
|
end
|
|
58
73
|
|
|
59
74
|
describe ".find_all" do
|
|
60
75
|
it "fetches multiple matching documents" do
|
|
61
|
-
|
|
76
|
+
stub_request(
|
|
62
77
|
:get,
|
|
63
78
|
"https://www.federalregister.gov/api/v1/documents/abc,def.json",
|
|
64
|
-
:content_type =>"text/json",
|
|
65
|
-
:body => {:results => [{:document_number => "abc"}, {:document_number => "def"}]}.to_json
|
|
66
79
|
)
|
|
80
|
+
.to_return(
|
|
81
|
+
body: {:results => [{:document_number => "abc"}, {:document_number => "def"}]}.to_json,
|
|
82
|
+
headers: { 'Content-Type' => 'text/json' },
|
|
83
|
+
)
|
|
84
|
+
|
|
67
85
|
result_set = FederalRegister::Document.find_all('abc','def')
|
|
68
86
|
result_set.results.map(&:document_number).sort.should === ['abc','def']
|
|
69
87
|
end
|
|
70
88
|
|
|
71
89
|
it "fetches multiple matching documents with only requested fields (when present)" do
|
|
72
|
-
|
|
90
|
+
params = URI.encode_www_form([["fields[]","document_number"],["fields[]", "title"]])
|
|
91
|
+
stub_request(
|
|
73
92
|
:get,
|
|
74
|
-
"https://www.federalregister.gov/api/v1/documents/abc,def.json
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
93
|
+
"https://www.federalregister.gov/api/v1/documents/abc,def.json?#{params}",
|
|
94
|
+
)
|
|
95
|
+
.to_return(
|
|
96
|
+
body: {:results => [{:document_number => "abc", :title => "Important Notice"},
|
|
97
|
+
{:document_number => "def", :title => "Important Rule"}]}.to_json,
|
|
98
|
+
headers: { 'Content-Type' => 'text/json' },
|
|
78
99
|
)
|
|
100
|
+
|
|
79
101
|
result_set = FederalRegister::Document.find_all('abc','def', :fields => ["document_number", "title"])
|
|
80
102
|
result_set.results.map(&:document_number).sort.should === ['abc','def']
|
|
81
103
|
result_set.results.map(&:title).sort.should === ['Important Notice','Important Rule']
|
|
82
104
|
result_set.results.map(&:start_page).should === [nil, nil]
|
|
83
105
|
end
|
|
106
|
+
|
|
107
|
+
it "handles results when no documents are returned" do
|
|
108
|
+
params = URI.encode_www_form([["fields[]","document_number"],["fields[]", "title"]])
|
|
109
|
+
stub_request(
|
|
110
|
+
:get,
|
|
111
|
+
"https://www.federalregister.gov/api/v1/documents/bad_document_number,.json?#{params}",
|
|
112
|
+
)
|
|
113
|
+
.to_return(
|
|
114
|
+
body: {"count":0,"results":[],"errors":{"not_found":["bad_docuemnt_number"]}}.to_json,
|
|
115
|
+
headers: { 'Content-Type' => 'text/json' },
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
result_set = FederalRegister::Document.find_all('bad_document_number', :fields => ["document_number", "title"])
|
|
119
|
+
result_set.count.should == 0
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
it "appends a trailing comma when a single document is provided to ensure API interface doesn't return a single document" do
|
|
123
|
+
params = URI.encode_www_form([["fields[]","document_number"],["fields[]", "title"]])
|
|
124
|
+
stub_request(
|
|
125
|
+
:get,
|
|
126
|
+
"https://www.federalregister.gov/api/v1/documents/2016-26522,.json?#{params}",
|
|
127
|
+
)
|
|
128
|
+
.to_return(
|
|
129
|
+
body: {:results => [{:document_number => "2016-26522", :title => "Important Notice"}],
|
|
130
|
+
}.to_json,
|
|
131
|
+
headers: { 'Content-Type' => 'text/json' },
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
FederalRegister::Document.find_all('2016-26522', :fields => ["document_number", "title"])
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
it "ensures document or citation numbers provided are unique before making requests to API Core." do
|
|
138
|
+
# Without calling unique, duplicate results could be returned since we're now batching up larger requests.
|
|
139
|
+
params = URI.encode_www_form([["fields[]","document_number"],["fields[]", "title"]])
|
|
140
|
+
stub_request(
|
|
141
|
+
:get,
|
|
142
|
+
"https://www.federalregister.gov/api/v1/documents/2016-26522,.json?#{params}",
|
|
143
|
+
)
|
|
144
|
+
.to_return(
|
|
145
|
+
:body => {:results => [{:document_number => "2016-26522", :title => "Important Notice"}],
|
|
146
|
+
}.to_json,
|
|
147
|
+
headers: { 'Content-Type' => 'text/json' },
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
FederalRegister::Document.find_all('2016-26522', '2016-26522', :fields => ["document_number", "title"])
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
#TODO: Add specs aroudn API response
|
|
154
|
+
it "batches up large requests when CGI parameters exceed the URL limit and returns the correct" do
|
|
155
|
+
params = URI.encode_www_form([["fields[]","document_number"],["fields[]", "title"]])
|
|
156
|
+
stub_request(
|
|
157
|
+
:get,
|
|
158
|
+
"https://www.federalregister.gov/api/v1/documents/2016-26000,2016-26001,2016-26002,2016-26003,2016-26004,2016-26005,2016-26006,2016-26007,2016-26008,2016-26009,2016-26010,2016-26011,2016-26012,2016-26013,2016-26014,2016-26015,2016-26016,2016-26017,2016-26018,2016-26019,2016-26020,2016-26021,2016-26022,2016-26023,2016-26024,2016-26025,2016-26026,2016-26027,2016-26028,2016-26029,2016-26030,2016-26031,2016-26032,2016-26033,2016-26034,2016-26035,2016-26036,2016-26037,2016-26038,2016-26039,2016-26040,2016-26041,2016-26042,2016-26043,2016-26044,2016-26045,2016-26046,2016-26047,2016-26048,2016-26049,2016-26050,2016-26051,2016-26052,2016-26053,2016-26054,2016-26055,2016-26056,2016-26057,2016-26058,2016-26059,2016-26060,2016-26061,2016-26062,2016-26063,2016-26064,2016-26065,2016-26066,2016-26067,2016-26068,2016-26069,2016-26070,2016-26071,2016-26072,2016-26073,2016-26074,2016-26075,2016-26076,2016-26077,2016-26078,2016-26079,2016-26080,2016-26081,2016-26082,2016-26083,2016-26084,2016-26085,2016-26086,2016-26087,2016-26088,2016-26089,2016-26090,2016-26091,2016-26092,2016-26093,2016-26094,2016-26095,2016-26096,2016-26097,2016-26098,2016-26099,2016-26100.json?#{params}"
|
|
159
|
+
)
|
|
160
|
+
.to_return(
|
|
161
|
+
:body => {:results => [
|
|
162
|
+
{:document_number => "2016-26000", :title => "Important Notice"},
|
|
163
|
+
#...
|
|
164
|
+
]}.to_json,
|
|
165
|
+
headers: { 'Content-Type' => 'text/json' }
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
stub_request(
|
|
169
|
+
:get,
|
|
170
|
+
"https://www.federalregister.gov/api/v1/documents/2016-26101,2016-26102,2016-26103,2016-26104,2016-26105,2016-26106,2016-26107,2016-26108,2016-26109,2016-26110,2016-26111,2016-26112,2016-26113,2016-26114,2016-26115,2016-26116,2016-26117,2016-26118,2016-26119,2016-26120,2016-26121,2016-26122,2016-26123,2016-26124,2016-26125,2016-26126,2016-26127,2016-26128,2016-26129,2016-26130,2016-26131,2016-26132,2016-26133,2016-26134,2016-26135,2016-26136,2016-26137,2016-26138,2016-26139,2016-26140,2016-26141,2016-26142,2016-26143,2016-26144,2016-26145,2016-26146,2016-26147,2016-26148,2016-26149,2016-26150,2016-26151,2016-26152,2016-26153,2016-26154,2016-26155,2016-26156,2016-26157,2016-26158,2016-26159,2016-26160,2016-26161,2016-26162,2016-26163,2016-26164,2016-26165,2016-26166,2016-26167,2016-26168,2016-26169,2016-26170,2016-26171,2016-26172,2016-26173,2016-26174,2016-26175,2016-26176,2016-26177,2016-26178,2016-26179,2016-26180,2016-26181,2016-26182,2016-26183,2016-26184,2016-26185,2016-26186,2016-26187,2016-26188,2016-26189,2016-26190,2016-26191,2016-26192,2016-26193,2016-26194,2016-26195,2016-26196,2016-26197,2016-26198,2016-26199,2016-26200.json?#{params}"
|
|
171
|
+
)
|
|
172
|
+
.to_return(
|
|
173
|
+
:body => {:results => [
|
|
174
|
+
{:document_number => "2016-26000", :title => "Important Notice"},
|
|
175
|
+
#...
|
|
176
|
+
]}.to_json,
|
|
177
|
+
headers: { 'Content-Type' => 'text/json' }
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
document_numbers = []
|
|
181
|
+
doc_suffix = 26000
|
|
182
|
+
201.times { document_numbers << "2016-#{doc_suffix}"; doc_suffix += 1 }
|
|
183
|
+
|
|
184
|
+
result_set = FederalRegister::Document.find_all(*document_numbers, :fields => ["document_number", "title"])
|
|
185
|
+
|
|
186
|
+
result_set.count.should == 2
|
|
187
|
+
result_set.previous.should == nil
|
|
188
|
+
result_set.next.should == nil
|
|
189
|
+
result_set.total_pages.should == nil
|
|
190
|
+
end
|
|
84
191
|
end
|
|
85
192
|
|
|
86
193
|
describe ".search" do
|
|
87
194
|
before(:each) do
|
|
88
|
-
|
|
195
|
+
params = URI.encode_www_form([["conditions[term]","Fish"]])
|
|
196
|
+
stub_request(
|
|
89
197
|
:get,
|
|
90
|
-
"https://www.federalregister.gov/api/v1/documents.json
|
|
91
|
-
|
|
92
|
-
|
|
198
|
+
"https://www.federalregister.gov/api/v1/documents.json?#{params}",
|
|
199
|
+
)
|
|
200
|
+
.to_return(
|
|
201
|
+
:body => {:count => 3}.to_json,
|
|
202
|
+
headers: { 'Content-Type' => 'text/json' },
|
|
93
203
|
)
|
|
94
204
|
end
|
|
95
205
|
|
|
@@ -102,12 +212,15 @@ describe FederalRegister::Document do
|
|
|
102
212
|
it "fetches the full_text_xml from the full_text_xml_url" do
|
|
103
213
|
url = "http://example.com/full_text"
|
|
104
214
|
document = FederalRegister::Document.new("full_text_xml_url" => url)
|
|
105
|
-
|
|
215
|
+
stub_request(
|
|
106
216
|
:get,
|
|
107
217
|
url,
|
|
108
|
-
:content_type =>"text/xml",
|
|
109
|
-
:body => "hello, world!"
|
|
110
218
|
)
|
|
219
|
+
.to_return(
|
|
220
|
+
:body => "hello, world!",
|
|
221
|
+
headers: { 'Content-Type' => 'text/xml' },
|
|
222
|
+
)
|
|
223
|
+
|
|
111
224
|
document.full_text_xml.should == 'hello, world!'
|
|
112
225
|
end
|
|
113
226
|
end
|
|
@@ -122,11 +235,13 @@ describe FederalRegister::Document do
|
|
|
122
235
|
describe "#docket_ids" do
|
|
123
236
|
it "returns an array" do
|
|
124
237
|
document_number = "2010-213"
|
|
125
|
-
|
|
238
|
+
stub_request(
|
|
126
239
|
:get,
|
|
127
240
|
"https://www.federalregister.gov/api/v1/documents/#{document_number}.json",
|
|
128
|
-
|
|
129
|
-
|
|
241
|
+
)
|
|
242
|
+
.to_return(
|
|
243
|
+
body: {:title => "Important Notice", :docket_ids => ['ABC','123']}.to_json,
|
|
244
|
+
headers: { 'Content-Type' => 'text/json' },
|
|
130
245
|
)
|
|
131
246
|
|
|
132
247
|
FederalRegister::Document.find(document_number).docket_ids.should == ['ABC','123']
|
|
@@ -4,36 +4,40 @@ describe FederalRegister::PublicInspectionDocument do
|
|
|
4
4
|
describe ".find" do
|
|
5
5
|
it "fetches the document by its document number" do
|
|
6
6
|
document_number = "2010-213"
|
|
7
|
-
|
|
7
|
+
stub_request(
|
|
8
8
|
:get,
|
|
9
|
-
"https://www.federalregister.gov/api/v1/public-inspection-documents/#{document_number}.json"
|
|
10
|
-
:content_type =>"text/json",
|
|
11
|
-
:body => {:title => "Important Notice"}.to_json
|
|
9
|
+
"https://www.federalregister.gov/api/v1/public-inspection-documents/#{document_number}.json"
|
|
12
10
|
)
|
|
11
|
+
.to_return(
|
|
12
|
+
body: {:title => "Important Notice"}.to_json,
|
|
13
|
+
headers: { 'Content-Type' => 'application/json' },
|
|
14
|
+
status: 200
|
|
15
|
+
)
|
|
16
|
+
|
|
13
17
|
|
|
14
18
|
FederalRegister::PublicInspectionDocument.find(document_number).title.should == 'Important Notice'
|
|
15
19
|
end
|
|
16
20
|
|
|
17
21
|
it "throws an error when a document doesn't exist" do
|
|
18
22
|
document_number = "some-random-document"
|
|
19
|
-
|
|
23
|
+
stub_request(
|
|
20
24
|
:get,
|
|
21
|
-
"https://www.federalregister.gov/api/v1/public-inspection-documents/#{document_number}.json"
|
|
22
|
-
|
|
23
|
-
|
|
25
|
+
"https://www.federalregister.gov/api/v1/public-inspection-documents/#{document_number}.json"
|
|
26
|
+
)
|
|
27
|
+
.to_return(
|
|
28
|
+
headers: { 'Content-Type' => 'text/json' },
|
|
29
|
+
status: 404
|
|
24
30
|
)
|
|
31
|
+
|
|
25
32
|
lambda{ FederalRegister::PublicInspectionDocument.find(document_number) }.should raise_error FederalRegister::Client::RecordNotFound
|
|
26
33
|
end
|
|
27
34
|
end
|
|
28
35
|
|
|
29
36
|
describe ".find_all" do
|
|
30
37
|
it "fetches multiple matching documents" do
|
|
31
|
-
|
|
32
|
-
:
|
|
33
|
-
|
|
34
|
-
:content_type =>"text/json",
|
|
35
|
-
:body => {:results => [{:document_number => "abc"}, {:document_number => "def"}]}.to_json
|
|
36
|
-
)
|
|
38
|
+
stub_request(:get, "https://www.federalregister.gov/api/v1/public-inspection-documents/abc,def.json").
|
|
39
|
+
to_return(status: 200, body: {:results => [{:document_number => "abc"}, {:document_number => "def"}]}.to_json, headers: { 'Content-Type' => 'text/json' })
|
|
40
|
+
|
|
37
41
|
result_set = FederalRegister::PublicInspectionDocument.find_all('abc','def')
|
|
38
42
|
result_set.results.map(&:document_number).sort.should === ['abc','def']
|
|
39
43
|
end
|
|
@@ -41,12 +45,18 @@ describe FederalRegister::PublicInspectionDocument do
|
|
|
41
45
|
|
|
42
46
|
describe ".available_on" do
|
|
43
47
|
it "fetches the document on PI on a given date" do
|
|
44
|
-
|
|
48
|
+
params = URI.encode_www_form([["conditions[available_on]", "2011-10-15"]])
|
|
49
|
+
|
|
50
|
+
stub_request(
|
|
45
51
|
:get,
|
|
46
|
-
"https://www.federalregister.gov/api/v1/public-inspection-documents.json
|
|
47
|
-
|
|
48
|
-
|
|
52
|
+
"https://www.federalregister.gov/api/v1/public-inspection-documents.json?#{params}",
|
|
53
|
+
)
|
|
54
|
+
.to_return(
|
|
55
|
+
body: {:results => [{:document_number => "abc"}, {:document_number => "def"}]}.to_json,
|
|
56
|
+
headers: { 'Content-Type' => 'text/json' },
|
|
57
|
+
# status: 200
|
|
49
58
|
)
|
|
59
|
+
|
|
50
60
|
result_set = FederalRegister::PublicInspectionDocument.available_on(Date.parse('2011-10-15'))
|
|
51
61
|
result_set.results.map(&:document_number).sort.should === ['abc','def']
|
|
52
62
|
end
|
|
@@ -54,12 +64,16 @@ describe FederalRegister::PublicInspectionDocument do
|
|
|
54
64
|
|
|
55
65
|
describe ".current" do
|
|
56
66
|
it "fetches the PI documents from the current issue" do
|
|
57
|
-
|
|
67
|
+
stub_request(
|
|
58
68
|
:get,
|
|
59
69
|
"https://www.federalregister.gov/api/v1/public-inspection-documents/current.json",
|
|
60
|
-
:content_type =>"text/json",
|
|
61
|
-
:body => {:results => [{:document_number => "abc"}, {:document_number => "def"}]}.to_json
|
|
62
70
|
)
|
|
71
|
+
.to_return(
|
|
72
|
+
body: {:results => [{:document_number => "abc"}, {:document_number => "def"}]}.to_json,
|
|
73
|
+
headers: { 'Content-Type' => 'text/json' },
|
|
74
|
+
# status: 200
|
|
75
|
+
)
|
|
76
|
+
|
|
63
77
|
result_set = FederalRegister::PublicInspectionDocument.current
|
|
64
78
|
result_set.results.map(&:document_number).sort.should === ['abc','def']
|
|
65
79
|
end
|
data/spec/result_set_spec.rb
CHANGED
|
@@ -3,7 +3,16 @@ require File.dirname(__FILE__) + '/spec_helper'
|
|
|
3
3
|
describe FederalRegister::ResultSet do
|
|
4
4
|
describe "#next" do
|
|
5
5
|
it "loads the next_page_url" do
|
|
6
|
-
|
|
6
|
+
stub_request(
|
|
7
|
+
:get,
|
|
8
|
+
"https://www.federalregister.gov/api/v1/fishes?page=2"
|
|
9
|
+
)
|
|
10
|
+
.to_return(
|
|
11
|
+
body: {:count => 24}.to_json,
|
|
12
|
+
headers: { 'Content-Type' => 'application/json' },
|
|
13
|
+
status: 200
|
|
14
|
+
)
|
|
15
|
+
|
|
7
16
|
FederalRegister::ResultSet.new({'next_page_url' => 'https://www.federalregister.gov/api/v1/fishes?page=2'}, FederalRegister::Document).next.count.should == 24
|
|
8
17
|
end
|
|
9
18
|
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
|
2
2
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
|
3
3
|
require 'rspec'
|
|
4
|
-
require '
|
|
4
|
+
require 'webmock/rspec'
|
|
5
5
|
require 'active_support/ordered_hash'
|
|
6
6
|
require 'active_support/json'
|
|
7
7
|
require 'active_support/time'
|
|
8
8
|
require 'federal_register'
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
WebMock.disable_net_connect!(allow_localhost: true) # Prevents real HTTP requests except to localhost
|
|
11
11
|
|
|
12
12
|
# Requires supporting files with custom matchers and macros, etc,
|
|
13
13
|
# in ./support/ and its subdirectories.
|
|
@@ -16,5 +16,3 @@ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
|
|
16
16
|
RSpec.configure do |config|
|
|
17
17
|
config.expect_with(:rspec) { |c| c.syntax = :should }
|
|
18
18
|
end
|
|
19
|
-
|
|
20
|
-
|
metadata
CHANGED
|
@@ -1,30 +1,29 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: federal_register
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.8.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrew Carpenter
|
|
8
8
|
- Bob Burbach
|
|
9
|
-
autorequire:
|
|
10
9
|
bindir: bin
|
|
11
10
|
cert_chain: []
|
|
12
11
|
date: 2019-12-03 00:00:00.000000000 Z
|
|
13
12
|
dependencies:
|
|
14
13
|
- !ruby/object:Gem::Dependency
|
|
15
|
-
name:
|
|
14
|
+
name: faraday
|
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
|
17
16
|
requirements:
|
|
18
17
|
- - ">="
|
|
19
18
|
- !ruby/object:Gem::Version
|
|
20
|
-
version:
|
|
19
|
+
version: '1.8'
|
|
21
20
|
type: :runtime
|
|
22
21
|
prerelease: false
|
|
23
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
24
23
|
requirements:
|
|
25
24
|
- - ">="
|
|
26
25
|
- !ruby/object:Gem::Version
|
|
27
|
-
version:
|
|
26
|
+
version: '1.8'
|
|
28
27
|
- !ruby/object:Gem::Dependency
|
|
29
28
|
name: shoulda
|
|
30
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -95,6 +94,20 @@ dependencies:
|
|
|
95
94
|
- - "~>"
|
|
96
95
|
- !ruby/object:Gem::Version
|
|
97
96
|
version: 1.3.0
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: webmock
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - ">="
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '0'
|
|
104
|
+
type: :development
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - ">="
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '0'
|
|
98
111
|
- !ruby/object:Gem::Dependency
|
|
99
112
|
name: rubocop
|
|
100
113
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -109,6 +122,34 @@ dependencies:
|
|
|
109
122
|
- - ">="
|
|
110
123
|
- !ruby/object:Gem::Version
|
|
111
124
|
version: '0'
|
|
125
|
+
- !ruby/object:Gem::Dependency
|
|
126
|
+
name: rspec_junit_formatter
|
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - ">="
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '0'
|
|
132
|
+
type: :development
|
|
133
|
+
prerelease: false
|
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - ">="
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: '0'
|
|
139
|
+
- !ruby/object:Gem::Dependency
|
|
140
|
+
name: pry
|
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
|
142
|
+
requirements:
|
|
143
|
+
- - ">="
|
|
144
|
+
- !ruby/object:Gem::Version
|
|
145
|
+
version: '0'
|
|
146
|
+
type: :development
|
|
147
|
+
prerelease: false
|
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
149
|
+
requirements:
|
|
150
|
+
- - ">="
|
|
151
|
+
- !ruby/object:Gem::Version
|
|
152
|
+
version: '0'
|
|
112
153
|
description: Ruby API Client for FederalRegister.gov that handles searching documents
|
|
113
154
|
and getting information about agencies
|
|
114
155
|
email: andrew@criticaljuncture.org
|
|
@@ -136,6 +177,7 @@ files:
|
|
|
136
177
|
- lib/federal_register/document.rb
|
|
137
178
|
- lib/federal_register/document_image.rb
|
|
138
179
|
- lib/federal_register/document_search_details.rb
|
|
180
|
+
- lib/federal_register/document_utilities.rb
|
|
139
181
|
- lib/federal_register/facet.rb
|
|
140
182
|
- lib/federal_register/facet/agency.rb
|
|
141
183
|
- lib/federal_register/facet/document.rb
|
|
@@ -180,7 +222,6 @@ homepage: http://github.com/usnationalarchives/federal_register
|
|
|
180
222
|
licenses:
|
|
181
223
|
- MIT
|
|
182
224
|
metadata: {}
|
|
183
|
-
post_install_message:
|
|
184
225
|
rdoc_options: []
|
|
185
226
|
require_paths:
|
|
186
227
|
- lib
|
|
@@ -195,9 +236,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
195
236
|
- !ruby/object:Gem::Version
|
|
196
237
|
version: '0'
|
|
197
238
|
requirements: []
|
|
198
|
-
|
|
199
|
-
rubygems_version: 2.7.6.2
|
|
200
|
-
signing_key:
|
|
239
|
+
rubygems_version: 3.6.2
|
|
201
240
|
specification_version: 3
|
|
202
241
|
summary: Ruby API Client for FederalRegister.gov
|
|
203
242
|
test_files: []
|