Skip to content

Commit

Permalink
Allow InContentStoreValidator to accept multiple schema names
Browse files Browse the repository at this point in the history
This validator checks whether a piece of content in Content Store
matches a given schema name.

Sometimes we may wish to accept multiple names, so updating the
validator to accept an array.
  • Loading branch information
brucebolt committed Aug 1, 2024
1 parent e1a738f commit c0ba00a
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 21 deletions.
2 changes: 1 addition & 1 deletion app/models/publishing_api_redirected_manual.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class PublishingAPIRedirectedManual

validates :manual_slug, :destination_manual_slug, format: { with: ValidSlug::PATTERN, message: "should match the pattern: #{ValidSlug::PATTERN}" }
validates_with InContentStoreValidator,
schema_name: MANUAL_SCHEMA_NAME,
schema_names: [MANUAL_SCHEMA_NAME],
content_store: Services.content_store,
unless: lambda {
errors[:manual_slug].present? || errors[:destination_manual_slug].present?
Expand Down
2 changes: 1 addition & 1 deletion app/models/publishing_api_redirected_section.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class PublishingAPIRedirectedSection
validates :manual_slug, :section_slug, :destination_manual_slug, format: { with: ValidSlug::PATTERN, message: "should match the pattern: #{ValidSlug::PATTERN}" }
validates :destination_section_slug, format: { with: ValidSlug::PATTERN, message: "should match the pattern: #{ValidSlug::PATTERN}" }, allow_nil: true
validates_with InContentStoreValidator,
schema_name: SECTION_SCHEMA_NAME,
schema_names: [SECTION_SCHEMA_NAME],
content_store: Services.content_store,
unless: lambda {
errors[:manual_slug].present? ||
Expand Down
2 changes: 1 addition & 1 deletion app/models/publishing_api_removed_manual.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class PublishingAPIRemovedManual

validates :slug, format: { with: ValidSlug::PATTERN, message: "should match the pattern: #{ValidSlug::PATTERN}" }
validates_with InContentStoreValidator,
schema_name: MANUAL_SCHEMA_NAME,
schema_names: [MANUAL_SCHEMA_NAME],
content_store: Services.content_store,
unless: -> { errors[:slug].present? }

Expand Down
2 changes: 1 addition & 1 deletion app/models/publishing_api_removed_section.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class PublishingAPIRemovedSection

validates :manual_slug, :section_slug, format: { with: ValidSlug::PATTERN, message: "should match the pattern: #{ValidSlug::PATTERN}" }
validates_with InContentStoreValidator,
schema_name: SECTION_SCHEMA_NAME,
schema_names: [SECTION_SCHEMA_NAME],
content_store: Services.content_store,
unless: -> { errors[:manual_slug].present? || errors[:section_slug].present? }

Expand Down
16 changes: 8 additions & 8 deletions app/validators/in_content_store_validator.rb
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
class InContentStoreValidator < ActiveModel::Validator
attr_reader :schema_name, :content_store
attr_reader :schema_names, :content_store

def initialize(options = {})
super
raise "Must provide schema_name and content_store options to the validator" unless options[:schema_name] && options[:content_store]
raise 'Can\'t provide "gone" as a schema_name to the validator' if options[:schema_name] == "gone"
raise "Must provide schema_names and content_store options to the validator" unless options[:schema_names] && options[:content_store]
raise 'Can\'t provide "gone" as schema_names to the validator' if options[:schema_names].include?("gone")

@schema_name = options[:schema_name]
@schema_names = options[:schema_names]
@content_store = options[:content_store]
end

def validate(record)
content_item = fetch_content_item(record)
if content_item["schema_name"] != schema_name
record.errors.add(:base, wrong_schema_name_message(record, content_item))
unless schema_names.include?(content_item["schema_name"])
record.errors.add(:base, wrong_schema_names_message(record, content_item))
end
rescue GdsApi::HTTPNotFound
record.errors.add(:base, missing_message(record, content_item))
Expand All @@ -35,7 +35,7 @@ def gone_message(_record, _content_item)
'Exists in the content store, but is already "gone"'
end

def wrong_schema_name_message(_record, content_item)
%{Exists in the content store, but is not a "#{schema_name}" schema (it's a "#{content_item['schema_name']}" schema)}
def wrong_schema_names_message(_record, content_item)
%{Exists in the content store, but is not a "#{schema_names.join(',')}" schema (it's a "#{content_item['schema_name']}" schema)}
end
end
18 changes: 9 additions & 9 deletions spec/validators/in_content_store_validator_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
subject do
InContentStoreValidator.new(
content_store:,
schema_name:,
schema_names:,
)
end
let(:content_store) { Services.content_store }
let(:schema_name) { MANUAL_SCHEMA_NAME }
let(:schema_names) { [MANUAL_SCHEMA_NAME, "redirect"] }

let(:manual) { PublishingAPIManual.new(slug, attributes) }
let(:slug) { "some-slug" }
Expand All @@ -33,7 +33,7 @@
let(:content_item_schema_name) { "invalid-schema-name" }
it "returns an error" do
expect(subject.validate(manual).attribute).to eq(:base)
expect(subject.validate(manual).type).to eq("Exists in the content store, but is not a \"#{MANUAL_SCHEMA_NAME}\" schema (it's a \"invalid-schema-name\" schema)")
expect(subject.validate(manual).type).to eq("Exists in the content store, but is not a \"#{MANUAL_SCHEMA_NAME},redirect\" schema (it's a \"invalid-schema-name\" schema)")
end
end

Expand All @@ -60,26 +60,26 @@
end

context "without a value for schema_name" do
let(:schema_name) { nil }
let(:schema_names) { nil }

it "raises an error" do
expect { subject }.to raise_error(RuntimeError, "Must provide schema_name and content_store options to the validator")
expect { subject }.to raise_error(RuntimeError, "Must provide schema_names and content_store options to the validator")
end
end

context "without a value for content_store" do
let(:content_store) { nil }

it "raises an error" do
expect { subject }.to raise_error(RuntimeError, "Must provide schema_name and content_store options to the validator")
expect { subject }.to raise_error(RuntimeError, "Must provide schema_names and content_store options to the validator")
end
end

context "with 'gone' as the schema_name" do
let(:schema_name) { "gone" }
context "with 'gone' as one of the schema_names" do
let(:schema_names) { %w[gone] }

it "raises an error" do
expect { subject }.to raise_error(RuntimeError, "Can't provide \"gone\" as a schema_name to the validator")
expect { subject }.to raise_error(RuntimeError, "Can't provide \"gone\" as schema_names to the validator")
end
end
end

0 comments on commit c0ba00a

Please sign in to comment.