federal_register 0.7.6 → 0.7.7

Sign up to get free protection for your applications and to get access to all the features.
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