ecfr 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +11 -0
  3. data/.gitignore +11 -0
  4. data/.rspec +3 -0
  5. data/.rspec_parallel +4 -0
  6. data/.rubocop.yml +28 -0
  7. data/.yardopts +3 -0
  8. data/CHANGELOG.md +6 -0
  9. data/Dockerfile +6 -0
  10. data/Gemfile +6 -0
  11. data/Gemfile.lock +138 -0
  12. data/LICENSE.txt +21 -0
  13. data/README.md +133 -0
  14. data/Rakefile +12 -0
  15. data/bin/console +15 -0
  16. data/bin/setup +8 -0
  17. data/ecfr.gemspec +74 -0
  18. data/lib/ecfr/admin_service/agency/hierarchy.rb +27 -0
  19. data/lib/ecfr/admin_service/agency.rb +34 -0
  20. data/lib/ecfr/admin_service/api_documentation.rb +7 -0
  21. data/lib/ecfr/admin_service/base.rb +26 -0
  22. data/lib/ecfr/admin_service/build.rb +38 -0
  23. data/lib/ecfr/admin_service/ecfr_correction/cfr_reference.rb +17 -0
  24. data/lib/ecfr/admin_service/ecfr_correction.rb +78 -0
  25. data/lib/ecfr/admin_service/editorial_note/hierarchy.rb +19 -0
  26. data/lib/ecfr/admin_service/editorial_note.rb +40 -0
  27. data/lib/ecfr/admin_service/ibr_cfr_range/address.rb +17 -0
  28. data/lib/ecfr/admin_service/ibr_cfr_range/organization.rb +28 -0
  29. data/lib/ecfr/admin_service/ibr_cfr_range.rb +67 -0
  30. data/lib/ecfr/admin_service/issue/change.rb +19 -0
  31. data/lib/ecfr/admin_service/issue.rb +86 -0
  32. data/lib/ecfr/admin_service/site_notification.rb +34 -0
  33. data/lib/ecfr/admin_service/status.rb +7 -0
  34. data/lib/ecfr/attribute_caster.rb +72 -0
  35. data/lib/ecfr/attribute_method_definition.rb +92 -0
  36. data/lib/ecfr/base.rb +71 -0
  37. data/lib/ecfr/client.rb +318 -0
  38. data/lib/ecfr/common/hierarchy.rb +35 -0
  39. data/lib/ecfr/configuration.rb +58 -0
  40. data/lib/ecfr/constants.rb +21 -0
  41. data/lib/ecfr/default_documentation_setup.rb +39 -0
  42. data/lib/ecfr/default_status_setup.rb +46 -0
  43. data/lib/ecfr/diff_service/base.rb +17 -0
  44. data/lib/ecfr/diff_service/status.rb +34 -0
  45. data/lib/ecfr/extensible.rb +45 -0
  46. data/lib/ecfr/facet_attribute_method_definition.rb +47 -0
  47. data/lib/ecfr/faraday/user_agent/middleware.rb +14 -0
  48. data/lib/ecfr/ofr_profile_service/base.rb +20 -0
  49. data/lib/ecfr/ofr_profile_service/status.rb +7 -0
  50. data/lib/ecfr/parallel_client.rb +33 -0
  51. data/lib/ecfr/prince_xml_service/base.rb +17 -0
  52. data/lib/ecfr/prince_xml_service/pdf.rb +31 -0
  53. data/lib/ecfr/renderer_service/base.rb +31 -0
  54. data/lib/ecfr/renderer_service/content.rb +34 -0
  55. data/lib/ecfr/renderer_service/diff.rb +31 -0
  56. data/lib/ecfr/renderer_service/origin.rb +56 -0
  57. data/lib/ecfr/renderer_service/status.rb +7 -0
  58. data/lib/ecfr/request_representation.rb +12 -0
  59. data/lib/ecfr/search_service/api_documentation.rb +7 -0
  60. data/lib/ecfr/search_service/base.rb +23 -0
  61. data/lib/ecfr/search_service/content_version/count.rb +33 -0
  62. data/lib/ecfr/search_service/content_version/hierarchical_count.rb +17 -0
  63. data/lib/ecfr/search_service/content_version/hierarchical_count_node.rb +30 -0
  64. data/lib/ecfr/search_service/content_version/hierarchichal_result.rb +42 -0
  65. data/lib/ecfr/search_service/content_version/result.rb +110 -0
  66. data/lib/ecfr/search_service/content_version/suggestion.rb +76 -0
  67. data/lib/ecfr/search_service/content_version/summary.rb +27 -0
  68. data/lib/ecfr/search_service/content_version.rb +85 -0
  69. data/lib/ecfr/search_service/date_facet.rb +19 -0
  70. data/lib/ecfr/search_service/facet_base.rb +55 -0
  71. data/lib/ecfr/search_service/status.rb +7 -0
  72. data/lib/ecfr/search_service/title_facet.rb +18 -0
  73. data/lib/ecfr/subscriptions_service/base.rb +19 -0
  74. data/lib/ecfr/subscriptions_service/status.rb +7 -0
  75. data/lib/ecfr/subscriptions_service/subscription.rb +97 -0
  76. data/lib/ecfr/testing/extensions/admin_service/ecfr_correction_extensions.rb +13 -0
  77. data/lib/ecfr/testing/extensions/admin_service/issue_extensions.rb +13 -0
  78. data/lib/ecfr/testing/extensions/renderer_service/origin_extensions.rb +13 -0
  79. data/lib/ecfr/testing/extensions/search_service/content_version_result_extensions.rb +16 -0
  80. data/lib/ecfr/testing/extensions/search_service/date_facet_extensions.rb +13 -0
  81. data/lib/ecfr/testing/extensions/versioner_service/ancestors_extensions.rb +20 -0
  82. data/lib/ecfr/testing/extensions/versioner_service/title_extenstions.rb +16 -0
  83. data/lib/ecfr/testing/factories/admin_service/cfr_reference_factory.rb +14 -0
  84. data/lib/ecfr/testing/factories/admin_service/ecfr_correction_factory.rb +31 -0
  85. data/lib/ecfr/testing/factories/admin_service/issue_change_factory.rb +12 -0
  86. data/lib/ecfr/testing/factories/admin_service/issue_factory.rb +21 -0
  87. data/lib/ecfr/testing/factories/common/hierarchy_factory.rb +36 -0
  88. data/lib/ecfr/testing/factories/renderer_service/origin_factory.rb +32 -0
  89. data/lib/ecfr/testing/factories/search_service/content_version_count_factory.rb +20 -0
  90. data/lib/ecfr/testing/factories/search_service/content_version_result_factory.rb +76 -0
  91. data/lib/ecfr/testing/factories/search_service/date_facet_factory.rb +12 -0
  92. data/lib/ecfr/testing/factories/versioner_service/ancestors_factory.rb +26 -0
  93. data/lib/ecfr/testing/factories/versioner_service/metadata_node_info_factory.rb +15 -0
  94. data/lib/ecfr/testing/factories/versioner_service/node_summary_factory.rb +16 -0
  95. data/lib/ecfr/testing/factories/versioner_service/structure_factory.rb +57 -0
  96. data/lib/ecfr/testing/factories/versioner_service/title_factory.rb +36 -0
  97. data/lib/ecfr/testing/factory_bot_helpers/content_version.rb +38 -0
  98. data/lib/ecfr/testing/factory_bot_helpers/ecfr_gem_initialize_helpers.rb +51 -0
  99. data/lib/ecfr/testing/helpers/response_helper.rb +5 -0
  100. data/lib/ecfr/testing/strategies/ecfr_attribute_hash_strategy.rb +37 -0
  101. data/lib/ecfr/testing.rb +28 -0
  102. data/lib/ecfr/version.rb +5 -0
  103. data/lib/ecfr/versioner_service/ancestors/metadata_node_info.rb +22 -0
  104. data/lib/ecfr/versioner_service/ancestors/node_summary.rb +54 -0
  105. data/lib/ecfr/versioner_service/ancestors.rb +152 -0
  106. data/lib/ecfr/versioner_service/api_documentation.rb +7 -0
  107. data/lib/ecfr/versioner_service/base.rb +24 -0
  108. data/lib/ecfr/versioner_service/status.rb +7 -0
  109. data/lib/ecfr/versioner_service/structure.rb +120 -0
  110. data/lib/ecfr/versioner_service/title.rb +78 -0
  111. data/lib/ecfr/versioner_service/xml_content.rb +59 -0
  112. data/lib/ecfr.rb +90 -0
  113. data/lib/yard/attribute_handler.rb +87 -0
  114. data/lib/yard/metadata_handler.rb +87 -0
  115. 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,7 @@
1
+ module Ecfr
2
+ module SearchService
3
+ class Status < Base
4
+ include DefaultStatusSetup
5
+ end
6
+ end
7
+ 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,7 @@
1
+ module Ecfr
2
+ module SubscriptionsService
3
+ class Status < Base
4
+ include DefaultStatusSetup
5
+ end
6
+ end
7
+ 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,13 @@
1
+ class Ecfr::AdminService::Issue
2
+ extend ResponseHelper
3
+
4
+ def self.response_for(issues)
5
+ results = {
6
+ issues: issues.is_a?(Array) ? issues : [issues]
7
+ }.to_json
8
+
9
+ build(
10
+ response: stubbed_response(results)
11
+ )
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ class Ecfr::RendererService::Origin
2
+ extend ResponseHelper
3
+
4
+ def self.response_for(origins)
5
+ results = {
6
+ origins: origins.is_a?(Array) ? origins : [origins]
7
+ }
8
+
9
+ build(
10
+ response: stubbed_response(results.to_json)
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,13 @@
1
+ class Ecfr::SearchService::DateFacet
2
+ extend ResponseHelper
3
+
4
+ def self.response_for(date_facets)
5
+ results = {
6
+ dates: date_facets
7
+ }.to_json
8
+
9
+ build(
10
+ response: stubbed_response(results)
11
+ )
12
+ end
13
+ 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,12 @@
1
+ FactoryBot.define do
2
+ factory :issue_change, class: "Ecfr::AdminService::Issue::Change" do
3
+ skip_create
4
+
5
+ change_description { "5 CFR 123" }
6
+ change_type { :effective }
7
+
8
+ initialize_with {
9
+ new(attributes.deep_stringify_keys)
10
+ }
11
+ end
12
+ 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