ecfr 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.circleci/config.yml +11 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.rspec_parallel +4 -0
- data/.rubocop.yml +28 -0
- data/.yardopts +3 -0
- data/CHANGELOG.md +6 -0
- data/Dockerfile +6 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +138 -0
- data/LICENSE.txt +21 -0
- data/README.md +133 -0
- data/Rakefile +12 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/ecfr.gemspec +74 -0
- data/lib/ecfr/admin_service/agency/hierarchy.rb +27 -0
- data/lib/ecfr/admin_service/agency.rb +34 -0
- data/lib/ecfr/admin_service/api_documentation.rb +7 -0
- data/lib/ecfr/admin_service/base.rb +26 -0
- data/lib/ecfr/admin_service/build.rb +38 -0
- data/lib/ecfr/admin_service/ecfr_correction/cfr_reference.rb +17 -0
- data/lib/ecfr/admin_service/ecfr_correction.rb +78 -0
- data/lib/ecfr/admin_service/editorial_note/hierarchy.rb +19 -0
- data/lib/ecfr/admin_service/editorial_note.rb +40 -0
- data/lib/ecfr/admin_service/ibr_cfr_range/address.rb +17 -0
- data/lib/ecfr/admin_service/ibr_cfr_range/organization.rb +28 -0
- data/lib/ecfr/admin_service/ibr_cfr_range.rb +67 -0
- data/lib/ecfr/admin_service/issue/change.rb +19 -0
- data/lib/ecfr/admin_service/issue.rb +86 -0
- data/lib/ecfr/admin_service/site_notification.rb +34 -0
- data/lib/ecfr/admin_service/status.rb +7 -0
- data/lib/ecfr/attribute_caster.rb +72 -0
- data/lib/ecfr/attribute_method_definition.rb +92 -0
- data/lib/ecfr/base.rb +71 -0
- data/lib/ecfr/client.rb +318 -0
- data/lib/ecfr/common/hierarchy.rb +35 -0
- data/lib/ecfr/configuration.rb +58 -0
- data/lib/ecfr/constants.rb +21 -0
- data/lib/ecfr/default_documentation_setup.rb +39 -0
- data/lib/ecfr/default_status_setup.rb +46 -0
- data/lib/ecfr/diff_service/base.rb +17 -0
- data/lib/ecfr/diff_service/status.rb +34 -0
- data/lib/ecfr/extensible.rb +45 -0
- data/lib/ecfr/facet_attribute_method_definition.rb +47 -0
- data/lib/ecfr/faraday/user_agent/middleware.rb +14 -0
- data/lib/ecfr/ofr_profile_service/base.rb +20 -0
- data/lib/ecfr/ofr_profile_service/status.rb +7 -0
- data/lib/ecfr/parallel_client.rb +33 -0
- data/lib/ecfr/prince_xml_service/base.rb +17 -0
- data/lib/ecfr/prince_xml_service/pdf.rb +31 -0
- data/lib/ecfr/renderer_service/base.rb +31 -0
- data/lib/ecfr/renderer_service/content.rb +34 -0
- data/lib/ecfr/renderer_service/diff.rb +31 -0
- data/lib/ecfr/renderer_service/origin.rb +56 -0
- data/lib/ecfr/renderer_service/status.rb +7 -0
- data/lib/ecfr/request_representation.rb +12 -0
- data/lib/ecfr/search_service/api_documentation.rb +7 -0
- data/lib/ecfr/search_service/base.rb +23 -0
- data/lib/ecfr/search_service/content_version/count.rb +33 -0
- data/lib/ecfr/search_service/content_version/hierarchical_count.rb +17 -0
- data/lib/ecfr/search_service/content_version/hierarchical_count_node.rb +30 -0
- data/lib/ecfr/search_service/content_version/hierarchichal_result.rb +42 -0
- data/lib/ecfr/search_service/content_version/result.rb +110 -0
- data/lib/ecfr/search_service/content_version/suggestion.rb +76 -0
- data/lib/ecfr/search_service/content_version/summary.rb +27 -0
- data/lib/ecfr/search_service/content_version.rb +85 -0
- data/lib/ecfr/search_service/date_facet.rb +19 -0
- data/lib/ecfr/search_service/facet_base.rb +55 -0
- data/lib/ecfr/search_service/status.rb +7 -0
- data/lib/ecfr/search_service/title_facet.rb +18 -0
- data/lib/ecfr/subscriptions_service/base.rb +19 -0
- data/lib/ecfr/subscriptions_service/status.rb +7 -0
- data/lib/ecfr/subscriptions_service/subscription.rb +97 -0
- data/lib/ecfr/testing/extensions/admin_service/ecfr_correction_extensions.rb +13 -0
- data/lib/ecfr/testing/extensions/admin_service/issue_extensions.rb +13 -0
- data/lib/ecfr/testing/extensions/renderer_service/origin_extensions.rb +13 -0
- data/lib/ecfr/testing/extensions/search_service/content_version_result_extensions.rb +16 -0
- data/lib/ecfr/testing/extensions/search_service/date_facet_extensions.rb +13 -0
- data/lib/ecfr/testing/extensions/versioner_service/ancestors_extensions.rb +20 -0
- data/lib/ecfr/testing/extensions/versioner_service/title_extenstions.rb +16 -0
- data/lib/ecfr/testing/factories/admin_service/cfr_reference_factory.rb +14 -0
- data/lib/ecfr/testing/factories/admin_service/ecfr_correction_factory.rb +31 -0
- data/lib/ecfr/testing/factories/admin_service/issue_change_factory.rb +12 -0
- data/lib/ecfr/testing/factories/admin_service/issue_factory.rb +21 -0
- data/lib/ecfr/testing/factories/common/hierarchy_factory.rb +36 -0
- data/lib/ecfr/testing/factories/renderer_service/origin_factory.rb +32 -0
- data/lib/ecfr/testing/factories/search_service/content_version_count_factory.rb +20 -0
- data/lib/ecfr/testing/factories/search_service/content_version_result_factory.rb +76 -0
- data/lib/ecfr/testing/factories/search_service/date_facet_factory.rb +12 -0
- data/lib/ecfr/testing/factories/versioner_service/ancestors_factory.rb +26 -0
- data/lib/ecfr/testing/factories/versioner_service/metadata_node_info_factory.rb +15 -0
- data/lib/ecfr/testing/factories/versioner_service/node_summary_factory.rb +16 -0
- data/lib/ecfr/testing/factories/versioner_service/structure_factory.rb +57 -0
- data/lib/ecfr/testing/factories/versioner_service/title_factory.rb +36 -0
- data/lib/ecfr/testing/factory_bot_helpers/content_version.rb +38 -0
- data/lib/ecfr/testing/factory_bot_helpers/ecfr_gem_initialize_helpers.rb +51 -0
- data/lib/ecfr/testing/helpers/response_helper.rb +5 -0
- data/lib/ecfr/testing/strategies/ecfr_attribute_hash_strategy.rb +37 -0
- data/lib/ecfr/testing.rb +28 -0
- data/lib/ecfr/version.rb +5 -0
- data/lib/ecfr/versioner_service/ancestors/metadata_node_info.rb +22 -0
- data/lib/ecfr/versioner_service/ancestors/node_summary.rb +54 -0
- data/lib/ecfr/versioner_service/ancestors.rb +152 -0
- data/lib/ecfr/versioner_service/api_documentation.rb +7 -0
- data/lib/ecfr/versioner_service/base.rb +24 -0
- data/lib/ecfr/versioner_service/status.rb +7 -0
- data/lib/ecfr/versioner_service/structure.rb +120 -0
- data/lib/ecfr/versioner_service/title.rb +78 -0
- data/lib/ecfr/versioner_service/xml_content.rb +59 -0
- data/lib/ecfr.rb +90 -0
- data/lib/yard/attribute_handler.rb +87 -0
- data/lib/yard/metadata_handler.rb +87 -0
- metadata +389 -0
@@ -0,0 +1,85 @@
|
|
1
|
+
module Ecfr
|
2
|
+
module SearchService
|
3
|
+
class ContentVersion < Base
|
4
|
+
require_relative "./content_version/count"
|
5
|
+
require_relative "./content_version/hierarchichal_result"
|
6
|
+
require_relative "./content_version/result"
|
7
|
+
require_relative "./content_version/suggestion"
|
8
|
+
require_relative "./content_version/summary"
|
9
|
+
|
10
|
+
#
|
11
|
+
# Metadata about the number of matching items
|
12
|
+
#
|
13
|
+
# @param [<Hash>] args valid search arguments, see {Result.find}
|
14
|
+
#
|
15
|
+
# @return [<Count>] count metadata
|
16
|
+
#
|
17
|
+
def self.count(args)
|
18
|
+
lookup(Ecfr::SearchService::ContentVersion::Count).find(args)
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
# Search results in a hierarchical format with score data
|
23
|
+
#
|
24
|
+
# @param [<Hash>] args valid search arguments, see {Result.find}
|
25
|
+
#
|
26
|
+
# @return [<HierarchicalSearchCount>] hierarchical search results
|
27
|
+
#
|
28
|
+
def self.hierarchical_search(args)
|
29
|
+
lookup(
|
30
|
+
Ecfr::SearchService::ContentVersion::HierarchicalResult
|
31
|
+
).find(args)
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# Search results with excerpts and score data
|
36
|
+
#
|
37
|
+
# @param [<Hash>] args valid search arguments, see {Result.find}
|
38
|
+
#
|
39
|
+
# @return [<Result>] results of a search
|
40
|
+
#
|
41
|
+
def self.search(args)
|
42
|
+
lookup(Ecfr::SearchService::ContentVersion::Result).find(args)
|
43
|
+
end
|
44
|
+
|
45
|
+
#
|
46
|
+
# Suggestions based on the content of a search.
|
47
|
+
# Currently suggests direct link to a portion of the CFR when
|
48
|
+
# a CFR citation is detected as part of the `query`
|
49
|
+
#
|
50
|
+
# @param [<Hash>] args valid search arguments, see {Result.find}
|
51
|
+
#
|
52
|
+
# @return [<Suggestion>] search suggestions
|
53
|
+
#
|
54
|
+
def self.suggestions(args)
|
55
|
+
lookup(Ecfr::SearchService::ContentVersion::Suggestion).find(args)
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
# Summary of the search based on the arguments provided
|
60
|
+
# - summary only makes use of the :hierarchy and :query
|
61
|
+
# args currenly
|
62
|
+
#
|
63
|
+
# @param [<Hash>] args valid search arguments, see {Result.find}
|
64
|
+
#
|
65
|
+
# @return [<Summary>] A descriptive summary of the search
|
66
|
+
#
|
67
|
+
def self.summary(args)
|
68
|
+
lookup(Ecfr::SearchService::ContentVersion::Summary).find(args)
|
69
|
+
end
|
70
|
+
|
71
|
+
#
|
72
|
+
# Support inheritance by looking up class. See
|
73
|
+
# Ecfr::Extensible for details.
|
74
|
+
#
|
75
|
+
def self.lookup(klass)
|
76
|
+
if const_defined?("#{klass}::KLASS")
|
77
|
+
klass::KLASS
|
78
|
+
else
|
79
|
+
klass
|
80
|
+
end
|
81
|
+
end
|
82
|
+
private_class_method :lookup
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Ecfr
|
2
|
+
module SearchService
|
3
|
+
class DateFacet < FacetBase
|
4
|
+
include FacetAttributeMethodDefinition
|
5
|
+
|
6
|
+
result_key :dates
|
7
|
+
|
8
|
+
attribute :count, as: :value
|
9
|
+
attribute :date, type: :date, as: :key
|
10
|
+
|
11
|
+
# @param [<Symbol, String>] type currently only supports :daily
|
12
|
+
# @return [<DateFacet>] counts by date
|
13
|
+
def self.search(type, options = {})
|
14
|
+
# no-op documentation only
|
15
|
+
super(type, options)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Ecfr
|
2
|
+
module SearchService
|
3
|
+
class FacetBase < Base
|
4
|
+
COUNTS_PATH = "v1/counts"
|
5
|
+
|
6
|
+
#
|
7
|
+
# Retrive counts of changed CFR sections by date
|
8
|
+
#
|
9
|
+
# @param [<Hash>] args valid facet search parameters
|
10
|
+
# @option options [<Ecfr::SearchService::ContentVersion::Hierarchy>] :hierarchy levels of CFR hierarchy to limit the search to
|
11
|
+
# @option options [<String>] :last_modified_after ISO date
|
12
|
+
# @option options [<String>] :last_modified_on_or_after ISO date
|
13
|
+
# @option options [<String>] :last_modified_before ISO date
|
14
|
+
# @option options [<String>] :last_modified_on_or_before ISO date
|
15
|
+
# @option options [<String>] :query search terms
|
16
|
+
# @option options [<Boolean>] :reserved whether counts should be for Reserved content (default false)
|
17
|
+
# @option options [<Boolean>] :substantive whether counts should be for substantive content (default true)
|
18
|
+
#
|
19
|
+
# @return [<DateFacet>] counts by date
|
20
|
+
#
|
21
|
+
def self.search(type, args = {})
|
22
|
+
prepare_search_options(args)
|
23
|
+
|
24
|
+
perform(
|
25
|
+
:get,
|
26
|
+
counts_path(type),
|
27
|
+
params: args
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.counts_path(type)
|
32
|
+
"#{COUNTS_PATH}/#{type}"
|
33
|
+
end
|
34
|
+
private_class_method :counts_path
|
35
|
+
|
36
|
+
VALID_SEARCH_OPTIONS = %i[
|
37
|
+
hierarchy last_modified_after last_modified_on_or_after
|
38
|
+
last_modified_before last_modified_on_or_before query reserved
|
39
|
+
substantive
|
40
|
+
]
|
41
|
+
|
42
|
+
def self.prepare_search_options(args)
|
43
|
+
args.deep_symbolize_keys!
|
44
|
+
args.slice!(*VALID_SEARCH_OPTIONS)
|
45
|
+
|
46
|
+
if args[:hierarchy]
|
47
|
+
args[:hierarchy] = args[:hierarchy].slice(
|
48
|
+
*Ecfr::Constants::Hierarchy::HIERARCHY_LEVELS.map(&:to_sym)
|
49
|
+
)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
private_class_method :prepare_search_options
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Ecfr
|
2
|
+
module SearchService
|
3
|
+
class TitleFacet < FacetBase
|
4
|
+
include FacetAttributeMethodDefinition
|
5
|
+
|
6
|
+
result_key :titles
|
7
|
+
|
8
|
+
attribute :count, as: :value
|
9
|
+
attribute :title, as: :key
|
10
|
+
|
11
|
+
# @return [<TitleFacet>] counts by title
|
12
|
+
def self.search(options = {})
|
13
|
+
type = "titles"
|
14
|
+
super(type, options)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Ecfr
|
2
|
+
module SubscriptionsService
|
3
|
+
class Base < Ecfr::Base
|
4
|
+
require_relative "status"
|
5
|
+
|
6
|
+
require_relative "subscription"
|
7
|
+
|
8
|
+
SERVICE_PATH = "/api/subscriptions"
|
9
|
+
|
10
|
+
def self.base_url
|
11
|
+
Ecfr.config.subscriptions_service_url || Ecfr.config.base_url
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.service_name
|
15
|
+
"Subscriptions Service"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module Ecfr
|
2
|
+
module SubscriptionsService
|
3
|
+
class Subscription < Base
|
4
|
+
result_key :subscriptions
|
5
|
+
|
6
|
+
attribute :title,
|
7
|
+
desc: "a description of the subscription"
|
8
|
+
|
9
|
+
attribute :delivery_count,
|
10
|
+
type: :integer,
|
11
|
+
desc: "the number of times the subscription has been delivered"
|
12
|
+
attribute :id,
|
13
|
+
type: :integer,
|
14
|
+
desc: "the subscription id"
|
15
|
+
|
16
|
+
attribute :created_at,
|
17
|
+
type: :date,
|
18
|
+
desc: "date the subscription was created"
|
19
|
+
attribute :last_delivered_at,
|
20
|
+
type: :date,
|
21
|
+
desc: "last date this subscription had matches and was delivered"
|
22
|
+
|
23
|
+
# TODO: upgrade to a class
|
24
|
+
|
25
|
+
# @return [Hash] with "query", and "hierarchy" keys
|
26
|
+
attribute :parameters,
|
27
|
+
desc: "the subscription search parameters"
|
28
|
+
|
29
|
+
SUBSCRIPTIONS_PATH = "v1/subscriptions"
|
30
|
+
|
31
|
+
#
|
32
|
+
# Retrive a list of subscriptions for a user
|
33
|
+
#
|
34
|
+
# @param [<Integer>] user_id id of user
|
35
|
+
#
|
36
|
+
# @return [[<Subscription>]] an array of subscriptions
|
37
|
+
#
|
38
|
+
def self.get_subscriptions(user_id)
|
39
|
+
perform(
|
40
|
+
:get,
|
41
|
+
"#{SUBSCRIPTIONS_PATH}/#{user_id}.json",
|
42
|
+
client_options: basic_auth_client_options
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
#
|
47
|
+
# Create a subscription for a user
|
48
|
+
#
|
49
|
+
# @param [<Integer>] user_id id of user
|
50
|
+
# @param [<Hash>] subscription_data arguments
|
51
|
+
# required to create a subscription
|
52
|
+
# @option subscription_data [String] requesting_ip (required)
|
53
|
+
# @option subscription_data [Hash] search (required)
|
54
|
+
# @option subscription_data [String] search[:query] subscription search terms
|
55
|
+
# @option subscription_data [Ecfr::Common::Hierarchy] search[:hierarchy] hierarchy to limit subscription search
|
56
|
+
#
|
57
|
+
# @return [<Subscription>] the created subscription
|
58
|
+
#
|
59
|
+
def self.create_subscription(user_id, subscription_data)
|
60
|
+
perform(
|
61
|
+
:post,
|
62
|
+
"#{SUBSCRIPTIONS_PATH}/#{user_id}",
|
63
|
+
params: subscription_data,
|
64
|
+
client_options: basic_auth_client_options,
|
65
|
+
perform_options: {attributes_key: "subscription"}
|
66
|
+
)
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
# Delete a subscription
|
71
|
+
#
|
72
|
+
# @param [<Integer>] user_id id of user
|
73
|
+
# @param [<String>] token unique delete token
|
74
|
+
# @param [<String>] subscription_id id of subscription
|
75
|
+
#
|
76
|
+
# @return [[<Subscription>, <Integer>]] the deleted subscription and response code
|
77
|
+
#
|
78
|
+
def self.delete_subscription(user_id, token, subscription_id)
|
79
|
+
unsubscribe_data = {
|
80
|
+
token: token,
|
81
|
+
user_id: user_id,
|
82
|
+
subscription_id: subscription_id
|
83
|
+
}
|
84
|
+
|
85
|
+
subscription = perform(
|
86
|
+
:delete,
|
87
|
+
"#{SUBSCRIPTIONS_PATH}/unsubscribe",
|
88
|
+
params: unsubscribe_data,
|
89
|
+
client_options: basic_auth_client_options,
|
90
|
+
perform_options: {attributes_key: "subscription"}
|
91
|
+
)
|
92
|
+
|
93
|
+
[subscription, subscription.response_status]
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class Ecfr::AdminService::EcfrCorrection
|
2
|
+
extend ResponseHelper
|
3
|
+
|
4
|
+
def self.response_for(corrections)
|
5
|
+
results = {
|
6
|
+
ecfr_corrections: corrections.is_a?(Array) ? corrections : [corrections]
|
7
|
+
}.to_json
|
8
|
+
|
9
|
+
build(
|
10
|
+
response: stubbed_response(results)
|
11
|
+
)
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class Ecfr::SearchService::ContentVersion::Result
|
2
|
+
extend ResponseHelper
|
3
|
+
|
4
|
+
def self.response_for(content_versions)
|
5
|
+
content_versions = content_versions.is_a?(Array) ? content_versions : [content_versions]
|
6
|
+
|
7
|
+
results = {
|
8
|
+
results: content_versions,
|
9
|
+
meta: content_versions.first.fetch("meta", nil)
|
10
|
+
}.compact
|
11
|
+
|
12
|
+
build(
|
13
|
+
response: stubbed_response(results.to_json)
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class Ecfr::VersionerService::Ancestors
|
2
|
+
extend ResponseHelper
|
3
|
+
|
4
|
+
def self.response_for(ancestors)
|
5
|
+
# ancestors can be a hash of attributes from the :ancestors factory,
|
6
|
+
# or one+ NodeSummary attribute hashes from the :node_summary
|
7
|
+
# factory
|
8
|
+
results = if ancestors.is_a?(Hash) && ancestors.key?("ancestors")
|
9
|
+
ancestors
|
10
|
+
else
|
11
|
+
{
|
12
|
+
ancestors: ancestors.is_a?(Array) ? ancestors : [ancestors]
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
build(
|
17
|
+
response: stubbed_response(results.to_json)
|
18
|
+
)
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class Ecfr::VersionerService::Title
|
2
|
+
extend ResponseHelper
|
3
|
+
|
4
|
+
def self.response_for(titles)
|
5
|
+
titles = titles.is_a?(Array) ? titles : [titles]
|
6
|
+
|
7
|
+
results = {
|
8
|
+
titles: titles,
|
9
|
+
meta: titles.first.fetch("meta", nil)
|
10
|
+
}.compact
|
11
|
+
|
12
|
+
build(
|
13
|
+
response: stubbed_response(results.to_json)
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
FactoryBot.define do
|
2
|
+
factory :cfr_reference, class: "Ecfr::AdminService::EcfrCorrection::CfrReference" do
|
3
|
+
skip_create
|
4
|
+
|
5
|
+
cfr_reference { "1 CFR 1" }
|
6
|
+
hierarchy {
|
7
|
+
ecfr_attribute_hash(:hierarchy, title: "1", part: "1")
|
8
|
+
}
|
9
|
+
|
10
|
+
initialize_with {
|
11
|
+
new(attributes.deep_stringify_keys)
|
12
|
+
}
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
FactoryBot.define do
|
2
|
+
factory :ecfr_correction, class: "Ecfr::AdminService::EcfrCorrection" do
|
3
|
+
skip_create
|
4
|
+
|
5
|
+
corrective_action { "corrected" }
|
6
|
+
fr_citation { "84 FR 12345" }
|
7
|
+
|
8
|
+
id { 1 }
|
9
|
+
position { 1 }
|
10
|
+
title { 1 }
|
11
|
+
year { correction_year }
|
12
|
+
|
13
|
+
error_corrected { Date.parse("#{year}-03-03") }
|
14
|
+
error_occurred { Date.parse("#{year}-01-01") }
|
15
|
+
last_modified { error_corrected }
|
16
|
+
|
17
|
+
cfr_references {
|
18
|
+
[ecfr_attribute_hash(:cfr_reference)]
|
19
|
+
}
|
20
|
+
|
21
|
+
display_in_toc { false }
|
22
|
+
|
23
|
+
initialize_with {
|
24
|
+
new(attributes.deep_stringify_keys)
|
25
|
+
}
|
26
|
+
|
27
|
+
transient do
|
28
|
+
correction_year { 2017 }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
FactoryBot.define do
|
2
|
+
factory :issue, class: "Ecfr::AdminService::Issue" do
|
3
|
+
skip_create
|
4
|
+
|
5
|
+
description { "January 1, 2019" }
|
6
|
+
|
7
|
+
titles { [5, 7, 9] }
|
8
|
+
|
9
|
+
end_date { "2019-01-01" }
|
10
|
+
issue_date { "2019-01-01" }
|
11
|
+
start_date { "2019-01-01" }
|
12
|
+
|
13
|
+
changes {
|
14
|
+
[ecfr_attribute_hash(:issue_change)]
|
15
|
+
}
|
16
|
+
|
17
|
+
initialize_with {
|
18
|
+
new(attributes.deep_stringify_keys)
|
19
|
+
}
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
FactoryBot.define do
|
2
|
+
factory :hierarchy, class: "Ecfr::Common::Hierarchy" do
|
3
|
+
skip_create
|
4
|
+
|
5
|
+
title { nil }
|
6
|
+
subtitle { nil }
|
7
|
+
chapter { nil }
|
8
|
+
subchapter { nil }
|
9
|
+
part { nil }
|
10
|
+
subpart { nil }
|
11
|
+
subject_group { nil }
|
12
|
+
section { nil }
|
13
|
+
appendix { nil }
|
14
|
+
|
15
|
+
initialize_with {
|
16
|
+
new(attributes.deep_stringify_keys)
|
17
|
+
}
|
18
|
+
|
19
|
+
trait :with_defaults do
|
20
|
+
title { "1" }
|
21
|
+
subtitle { "A" }
|
22
|
+
chapter { "I" }
|
23
|
+
subchapter { "I" }
|
24
|
+
part { "1" }
|
25
|
+
subpart { "B" }
|
26
|
+
subject_group { nil }
|
27
|
+
section { "1.1" }
|
28
|
+
appendix { nil }
|
29
|
+
end
|
30
|
+
|
31
|
+
trait :appendix do
|
32
|
+
section { nil }
|
33
|
+
appendix { "Appendix A to Part 1" }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
FactoryBot.define do
|
2
|
+
factory :origin, class: "Ecfr::RendererService::Origin" do
|
3
|
+
skip_create
|
4
|
+
|
5
|
+
identifier { "121" }
|
6
|
+
label_level { "Part 121" }
|
7
|
+
level { "part" }
|
8
|
+
link { "/current/title-40/part-121" }
|
9
|
+
title { "Part 121" }
|
10
|
+
|
11
|
+
authority {
|
12
|
+
["Sec. 21 (b) and (c), 84 Stat. 91 (<a href=\"https://www.govinfo.gov/link/uscode/33/1171\" class=\"usc external\" target=\"_blank\" rel=\"noopener noreferrer\">33 U.S.C. 1171(b)</a> (1970)); Reorganization Plan No. 3 of 1970. "]
|
13
|
+
}
|
14
|
+
source {
|
15
|
+
["<a href=\"https://www.federalregister.gov/citation/36-FR-22487\" class=\"fr-reference\" data-reference=\"36 FR 22487\">36 FR 22487</a>, Nov. 25, 1971, unless otherwise noted. Redesignated at <a href=\"https://www.federalregister.gov/citation/37-FR-21441\" class=\"fr-reference\" data-reference=\"37 FR 21441\">37 FR 21441</a>, Oct. 11, 1972, and further redesignated at <a href=\"https://www.federalregister.gov/citation/44-FR-32899\" class=\"fr-reference\" data-reference=\"44 FR 32899\">44 FR 32899</a>, June 7, 1979. "]
|
16
|
+
}
|
17
|
+
|
18
|
+
current { false }
|
19
|
+
|
20
|
+
hierarchy {
|
21
|
+
ecfr_attribute_hash(:hierarchy,
|
22
|
+
title: "40",
|
23
|
+
chapter: "I",
|
24
|
+
subchapter: "D",
|
25
|
+
part: "121")
|
26
|
+
}
|
27
|
+
|
28
|
+
initialize_with {
|
29
|
+
new(attributes.deep_stringify_keys)
|
30
|
+
}
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
FactoryBot.define do
|
2
|
+
factory :content_version_count, class: "Ecfr::SearchService::ContentVersion::Count" do
|
3
|
+
skip_create
|
4
|
+
|
5
|
+
meta {
|
6
|
+
{
|
7
|
+
description: "Description of results...",
|
8
|
+
total_count: total_count
|
9
|
+
}
|
10
|
+
}
|
11
|
+
|
12
|
+
transient do
|
13
|
+
total_count { 10 }
|
14
|
+
end
|
15
|
+
|
16
|
+
initialize_with {
|
17
|
+
new(attributes.deep_stringify_keys)
|
18
|
+
}
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
FactoryBot.define do
|
2
|
+
factory :content_version_result, class: "Ecfr::SearchService::ContentVersion::Result" do
|
3
|
+
skip_create
|
4
|
+
|
5
|
+
change_types { [] }
|
6
|
+
|
7
|
+
full_text_excerpt {
|
8
|
+
"Section 100.100 full text excerpt with <strong>formatting</strong>"
|
9
|
+
}
|
10
|
+
|
11
|
+
hierarchy {
|
12
|
+
{
|
13
|
+
title: "10",
|
14
|
+
subtitle: "B",
|
15
|
+
chapter: "II",
|
16
|
+
subchapter: "H",
|
17
|
+
part: "100",
|
18
|
+
subpart: "D",
|
19
|
+
subject_group: nil,
|
20
|
+
section: (type == "Section") ? "100.100" : nil,
|
21
|
+
appendix: (type == "Appendix") ? "Appendix A to Subpart D of Part 100" : nil
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
# defaults for these are generated in helpers based on the hierarchy
|
26
|
+
# provided - any provided here will override just those keys
|
27
|
+
headings { {} }
|
28
|
+
hierarchy_headings { {} }
|
29
|
+
|
30
|
+
reserved { false }
|
31
|
+
removed { false }
|
32
|
+
|
33
|
+
score { 16.946056 }
|
34
|
+
structure_index { 1 }
|
35
|
+
|
36
|
+
starts_on { "2017-01-03" }
|
37
|
+
ends_on { nil }
|
38
|
+
|
39
|
+
type { "Section" }
|
40
|
+
|
41
|
+
trait :appendix do
|
42
|
+
type { "Appendix" }
|
43
|
+
end
|
44
|
+
|
45
|
+
meta {
|
46
|
+
{
|
47
|
+
current_page: current_page,
|
48
|
+
description: description,
|
49
|
+
min_date: min_date,
|
50
|
+
max_date: max_date,
|
51
|
+
max_score: max_score,
|
52
|
+
total_count: total_count,
|
53
|
+
total_pages: total_pages
|
54
|
+
}
|
55
|
+
}
|
56
|
+
|
57
|
+
transient do
|
58
|
+
current_page { 1 }
|
59
|
+
description { "Results for search terms x, y, and z" }
|
60
|
+
min_date { "2017-01-03" }
|
61
|
+
max_date { "2017-01-10" }
|
62
|
+
max_score { 1 }
|
63
|
+
total_count { 1 }
|
64
|
+
total_pages { 1 }
|
65
|
+
end
|
66
|
+
|
67
|
+
initialize_with {
|
68
|
+
attrs = FactoryBotHelpers::EcfrGemInitializeHelpers.pre_initialize_attrs_for(
|
69
|
+
:content_version_result,
|
70
|
+
attributes
|
71
|
+
)
|
72
|
+
|
73
|
+
new(attrs.deep_stringify_keys)
|
74
|
+
}
|
75
|
+
end
|
76
|
+
end
|