federal_register 0.7.6 → 0.7.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 63643d75cc0539e9244e7bcb4715569cdaabaa946467a527b14c3b1babc3f40c
4
- data.tar.gz: 1a0a8b76e5e2deb3dc215cf2109e117989cc983d3caf7189575b25a7ab01e480
3
+ metadata.gz: 29108ec013bfbdf370e3ac4b2c5f2de8312ee5ed0d42fa4314a4ec67349ddaa7
4
+ data.tar.gz: 81773b6cedce1060dd60b0bc811f81e47db875e9e2feb0eefd39b8ce707687ce
5
5
  SHA512:
6
- metadata.gz: 611b9c78a73332729c6fff76b56cc5d29e7ef5ecb1bae8357aaa8c7c9e1bef153c461235ec30b190c42a9ad83539572e198933ea59a611fd926173934b08799e
7
- data.tar.gz: d0e720e9af49fcb7655b201b09fea1550f2b4f9fd2f0eeffbad4cbb8bee1601e36bb017009c8edb2147a69bbb645777f4d358485e829f11ac244713916b84b56
6
+ metadata.gz: cfaafa77066a18b25c3fb8168e677b9d5cf332da4cde50112a2e945adc8d0eedbaca0045d96617b20fc0e28eacbf5e3d26cf0425fc9629af1f257236aa260db2
7
+ data.tar.gz: 71f6cab320067badb01768221dec911e9bf57d777594a28b2f658489ac2bcf4e1162b74ceeb5dd3a549a116748d07a953903be776c20f9212342770672ca04b7
data/Gemfile.lock CHANGED
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- federal_register (0.6.7)
5
- httparty (~> 0.14.0)
4
+ federal_register (0.7.7)
5
+ httparty (>= 0.14.0)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
@@ -14,10 +14,14 @@ GEM
14
14
  concurrent-ruby (1.0.5)
15
15
  diff-lcs (1.2.5)
16
16
  fakeweb (1.3.0)
17
- httparty (0.14.0)
17
+ httparty (0.18.1)
18
+ mime-types (~> 3.0)
18
19
  multi_xml (>= 0.5.2)
19
20
  i18n (0.9.1)
20
21
  concurrent-ruby (~> 1.0)
22
+ mime-types (3.3.1)
23
+ mime-types-data (~> 3.2015)
24
+ mime-types-data (3.2020.1104)
21
25
  multi_json (1.12.2)
22
26
  multi_xml (0.6.0)
23
27
  parallel (1.12.0)
@@ -35,6 +39,8 @@ GEM
35
39
  rspec-expectations (2.99.2)
36
40
  diff-lcs (>= 1.1.3, < 2.0)
37
41
  rspec-mocks (2.99.3)
42
+ rspec_junit_formatter (0.4.1)
43
+ rspec-core (>= 2, < 4, != 2.12.0)
38
44
  rubocop (0.51.0)
39
45
  parallel (~> 1.10)
40
46
  parser (>= 2.3.3.1, < 3.0)
@@ -60,8 +66,9 @@ DEPENDENCIES
60
66
  fakeweb (~> 1.3.0)
61
67
  federal_register!
62
68
  rspec (~> 2.6)
69
+ rspec_junit_formatter
63
70
  rubocop
64
71
  shoulda
65
72
 
66
73
  BUNDLED WITH
67
- 1.16.0
74
+ 2.1.4
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.7.6
1
+ 0.7.7
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "federal_register"
8
- s.version = "0.7.6"
8
+ s.version = "0.7.7"
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",
@@ -94,6 +95,7 @@ Gem::Specification.new do |s|
94
95
  s.add_development_dependency(%q<activesupport>, ["~> 3"])
95
96
  s.add_development_dependency(%q<fakeweb>, ["~> 1.3.0"])
96
97
  s.add_development_dependency(%q<rubocop>, [">= 0"])
98
+ s.add_development_dependency(%q<rspec_junit_formatter>, [">= 0"])
97
99
  else
98
100
  s.add_dependency(%q<httparty>, [">= 0.7.0"])
99
101
  s.add_dependency(%q<shoulda>, [">= 0"])
@@ -102,6 +104,7 @@ Gem::Specification.new do |s|
102
104
  s.add_dependency(%q<activesupport>, ["~> 3"])
103
105
  s.add_dependency(%q<fakeweb>, ["~> 1.3.0"])
104
106
  s.add_dependency(%q<rubocop>, [">= 0"])
107
+ s.add_dependency(%q<rspec_junit_formatter>, [">= 0"])
105
108
  end
106
109
  else
107
110
  s.add_dependency(%q<httparty>, [">= 0.14.0"])
@@ -111,5 +114,6 @@ Gem::Specification.new do |s|
111
114
  s.add_dependency(%q<activesupport>, ["~> 3"])
112
115
  s.add_dependency(%q<fakeweb>, ["~> 1.3.0"])
113
116
  s.add_dependency(%q<rubocop>, [">= 0"])
117
+ s.add_dependency(%q<rspec_junit_formatter>, [">= 0"])
114
118
  end
115
119
  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"
@@ -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,
@@ -77,23 +78,8 @@ class FederalRegister::Document < FederalRegister::Base
77
78
  new(attributes, :full => true)
78
79
  end
79
80
 
80
- # supports values like: '2016-26522', '2016-26522,2016-26594', '81 FR 76496', '81 FR 76496,81 FR 76685'
81
- # note: no space after comma
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
@@ -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,
@@ -43,21 +44,8 @@ class FederalRegister::PublicInspectionDocument < FederalRegister::Base
43
44
  FederalRegister::PublicInspectionIssueResultSet.fetch("/public-inspection-documents/current.json", :result_class => self)
44
45
  end
45
46
 
46
- def self.find_all(*args)
47
- options, document_numbers = extract_options(args)
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
@@ -16,9 +16,11 @@ describe FederalRegister::Document do
16
16
 
17
17
  it "fetches the document with only requested fields (when present)" do
18
18
  document_number = "2010-213"
19
+ params = URI.encode_www_form([["fields[]","title"],["fields[]", "start_page"]])
20
+
19
21
  FakeWeb.register_uri(
20
22
  :get,
21
- "https://www.federalregister.gov/api/v1/documents/#{document_number}.json?fields[]=title&fields[]=start_page",
23
+ "https://www.federalregister.gov/api/v1/documents/#{document_number}.json?#{params}",
22
24
  :content_type => "text/json",
23
25
  :body => {:title => "Important Notice", :start_page => 12345}.to_json
24
26
  )
@@ -32,9 +34,11 @@ describe FederalRegister::Document do
32
34
  it "fetches the document with the provided publication date (when present)" do
33
35
  document_number = "2010-213"
34
36
  publication_date = "2010-02-02"
37
+ params = URI.encode_www_form([["publication_date", "#{publication_date}"]])
38
+
35
39
  FakeWeb.register_uri(
36
40
  :get,
37
- "https://www.federalregister.gov/api/v1/documents/#{document_number}.json?publication_date=#{publication_date}",
41
+ "https://www.federalregister.gov/api/v1/documents/#{document_number}.json?#{params}",
38
42
  :content_type => "text/json",
39
43
  :body => {:title => "Important Notice", :publication_date => publication_date}.to_json
40
44
  )
@@ -69,9 +73,11 @@ describe FederalRegister::Document do
69
73
  end
70
74
 
71
75
  it "fetches multiple matching documents with only requested fields (when present)" do
76
+ params = URI.encode_www_form([["fields[]","document_number"],["fields[]", "title"]])
77
+
72
78
  FakeWeb.register_uri(
73
79
  :get,
74
- "https://www.federalregister.gov/api/v1/documents/abc,def.json?fields[]=document_number&fields[]=title",
80
+ "https://www.federalregister.gov/api/v1/documents/abc,def.json?#{params}",
75
81
  :content_type =>"text/json",
76
82
  :body => {:results => [{:document_number => "abc", :title => "Important Notice"},
77
83
  {:document_number => "def", :title => "Important Rule"}]}.to_json
@@ -81,13 +87,87 @@ describe FederalRegister::Document do
81
87
  result_set.results.map(&:title).sort.should === ['Important Notice','Important Rule']
82
88
  result_set.results.map(&:start_page).should === [nil, nil]
83
89
  end
90
+
91
+ it "handles results when no documents are returned" do
92
+ params = URI.encode_www_form([["fields[]","document_number"],["fields[]", "title"]])
93
+ FakeWeb.register_uri(
94
+ :get,
95
+ "https://www.federalregister.gov/api/v1/documents/bad_document_number,.json?#{params}",
96
+ :content_type =>"text/json",
97
+ :body => {"count":0,"results":[],"errors":{"not_found":["bad_docuemnt_number"]}}.to_json
98
+ )
99
+
100
+ result_set = FederalRegister::Document.find_all('bad_document_number', :fields => ["document_number", "title"])
101
+ result_set.count.should == 0
102
+ end
103
+
104
+ it "appends a trailing comma when a single document is provided to ensure API interface doesn't return a single document" do
105
+ params = URI.encode_www_form([["fields[]","document_number"],["fields[]", "title"]])
106
+ FakeWeb.register_uri(
107
+ :get,
108
+ "https://www.federalregister.gov/api/v1/documents/2016-26522,.json?#{params}",
109
+ :content_type =>"text/json",
110
+ :body => {:results => [{:document_number => "2016-26522", :title => "Important Notice"}],
111
+ }.to_json
112
+ )
113
+
114
+ FederalRegister::Document.find_all('2016-26522', :fields => ["document_number", "title"])
115
+ end
116
+
117
+ it "ensures document or citation numbers provided are unique before making requests to API Core." do
118
+ # Without calling unique, duplicate results could be returned since we're now batching up larger requests.
119
+ params = URI.encode_www_form([["fields[]","document_number"],["fields[]", "title"]])
120
+ FakeWeb.register_uri(
121
+ :get,
122
+ "https://www.federalregister.gov/api/v1/documents/2016-26522,.json?fields[]=#{params}",
123
+ :content_type =>"text/json",
124
+ :body => {:results => [{:document_number => "2016-26522", :title => "Important Notice"}],
125
+ }.to_json
126
+ )
127
+ FederalRegister::Document.find_all('2016-26522', '2016-26522', :fields => ["document_number", "title"])
128
+ end
129
+
130
+ #TODO: Add specs aroudn API response
131
+ it "batches up large requests when CGI parameters exceed the URL limit and returns the correct" do
132
+ params = URI.encode_www_form([["fields[]","document_number"],["fields[]", "title"]])
133
+ FakeWeb.register_uri(
134
+ :get,
135
+ "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}",
136
+ :content_type =>"text/json",
137
+ :body => {:results => [
138
+ {:document_number => "2016-26000", :title => "Important Notice"},
139
+ #...
140
+ ]}.to_json
141
+ )
142
+ FakeWeb.register_uri(
143
+ :get,
144
+ "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}",
145
+ :content_type =>"text/json",
146
+ :body => {:results => [
147
+ {:document_number => "2016-26000", :title => "Important Notice"},
148
+ #...
149
+ ]}.to_json
150
+ )
151
+
152
+ document_numbers = []
153
+ doc_suffix = 26000
154
+ 201.times { document_numbers << "2016-#{doc_suffix}"; doc_suffix += 1 }
155
+
156
+ result_set = FederalRegister::Document.find_all(*document_numbers, :fields => ["document_number", "title"])
157
+
158
+ result_set.count.should == 2
159
+ result_set.previous.should == nil
160
+ result_set.next.should == nil
161
+ result_set.total_pages.should == nil
162
+ end
84
163
  end
85
164
 
86
165
  describe ".search" do
87
166
  before(:each) do
167
+ params = URI.encode_www_form([["conditions[term]","Fish"]])
88
168
  FakeWeb.register_uri(
89
169
  :get,
90
- "https://www.federalregister.gov/api/v1/documents.json?conditions[term]=Fish",
170
+ "https://www.federalregister.gov/api/v1/documents.json?#{params}",
91
171
  :content_type =>"text/json",
92
172
  :body => {:count => 3}.to_json
93
173
  )
@@ -41,9 +41,10 @@ describe FederalRegister::PublicInspectionDocument do
41
41
 
42
42
  describe ".available_on" do
43
43
  it "fetches the document on PI on a given date" do
44
+ params = URI.encode_www_form([["conditions[available_on]", "2011-10-15"]])
44
45
  FakeWeb.register_uri(
45
46
  :get,
46
- "https://www.federalregister.gov/api/v1/public-inspection-documents.json?conditions[available_on]=2011-10-15",
47
+ "https://www.federalregister.gov/api/v1/public-inspection-documents.json?#{params}",
47
48
  :content_type =>"text/json",
48
49
  :body => {:results => [{:document_number => "abc"}, {:document_number => "def"}]}.to_json
49
50
  )
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: federal_register
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.6
4
+ version: 0.7.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Carpenter
@@ -109,6 +109,20 @@ dependencies:
109
109
  - - ">="
110
110
  - !ruby/object:Gem::Version
111
111
  version: '0'
112
+ - !ruby/object:Gem::Dependency
113
+ name: rspec_junit_formatter
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
112
126
  description: Ruby API Client for FederalRegister.gov that handles searching documents
113
127
  and getting information about agencies
114
128
  email: andrew@criticaljuncture.org
@@ -136,6 +150,7 @@ files:
136
150
  - lib/federal_register/document.rb
137
151
  - lib/federal_register/document_image.rb
138
152
  - lib/federal_register/document_search_details.rb
153
+ - lib/federal_register/document_utilities.rb
139
154
  - lib/federal_register/facet.rb
140
155
  - lib/federal_register/facet/agency.rb
141
156
  - lib/federal_register/facet/document.rb
@@ -195,8 +210,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
195
210
  - !ruby/object:Gem::Version
196
211
  version: '0'
197
212
  requirements: []
198
- rubyforge_project:
199
- rubygems_version: 2.7.6.2
213
+ rubygems_version: 3.1.2
200
214
  signing_key:
201
215
  specification_version: 3
202
216
  summary: Ruby API Client for FederalRegister.gov