describe "Fortitude attribute rules enforcement", :type => :system do
def widget_class(options = { }, &block)
out = super(options, &block)
out.class_eval { enforce_attribute_rules true } unless options.delete(:no_enforcement)
out
end
it "should not allow an attribute 'foo' on
" do
expect { render(widget_class_with_content { p :foo => 'bar' })}.to raise_error(Fortitude::Errors::InvalidElementAttributes)
end
it "should quote HTML specs at you when you screw up" do
expect { render(widget_class_with_content { p :foo => 'bar' })}.to raise_error(Fortitude::Errors::InvalidElementAttributes, /THE_SPEC_FOR_P/)
end
it "should allow an attribute 'class' on
" do
expect(render(widget_class_with_content { p :class => 'bar' })).to eq("
")
end
it "should allow arbitrary individual data-* attributes" do
result = render(widget_class_with_content { p :'data-foo' => 'bar', 'DATA-BAZ' => 'quux' })
expect([ '', '' ].include?(result)).to be
end
it "should allow a data attribute, specified as a Hash" do
result = render(widget_class_with_content { p :data => { :foo => 'bar', 'baz' => 'quux' }})
expect([ '', '' ].include?(result)).to be
end
it "should not allow a plain 'data' attribute" do
expect { render(widget_class_with_content { p :data => 'foo' }) }.to raise_error(Fortitude::Errors::InvalidElementAttributes)
end
it "should not allow a plain 'data-' attribute" do
expect { render(widget_class_with_content { p :'data-' => 'foo' }) }.to raise_error(Fortitude::Errors::InvalidElementAttributes)
end
def class_with_custom_tag(additional_attributes, &block)
out = widget_class
out.class_eval do
tag :mytag, { :valid_attributes => %w{foo bar} }.merge(additional_attributes)
end
out.class_eval(&block) if block
out
end
it "should allow data and ARIA attributes by default" do
klass = class_with_custom_tag({ }) do
def content
mytag :foo => 'bar', :data => { 'aaa' => 'bbb' }, :aria => { 'ccc' => 'ddd' }
end
end
result = render(klass)
expect(result).to match(%r{^$})
expect(result).to match(/foo=\"bar\"/)
expect(result).to match(/data-aaa=\"bbb\"/)
expect(result).to match(/aria-ccc=\"ddd\"/)
# expect(render(klass)).to eq("")
end
it "should not allow data attributes if told not to" do
klass = class_with_custom_tag(:allow_data_attributes => false) do
def content
mytag :foo => 'bar', :data => { :aaa => 'bbb' }
end
end
expect { render(klass) }.to raise_error(Fortitude::Errors::InvalidElementAttributes)
end
it "should not allow ARIA attributes if told not to" do
klass = class_with_custom_tag(:allow_aria_attributes => false) do
def content
mytag :foo => 'bar', :aria => { :ccc => 'ddd' }
end
end
expect { render(klass) }.to raise_error(Fortitude::Errors::InvalidElementAttributes)
end
it "should not enforce rules inside a widget with the setting off, even if surrounding widgets have it on" do
outer = widget_class do
attr_accessor :inner
def content
widget inner
end
end
middle = widget_class(:no_enforcement => true) do
attr_accessor :inner
def content
p :foo => 'bar'
widget inner
end
end
inner = widget_class_with_content do
text "yo"
end
outer_instance = outer.new
middle_instance = middle.new
inner_instance = inner.new
outer_instance.inner = middle_instance
middle_instance.inner = inner_instance
expect(render(outer_instance)).to eq("yo")
end
it "should allow you to disable attribute rules with a block" do
wc = widget_class_with_content do
begin
p :foo => 'bar'
rescue => e
text e.class.name
end
with_attribute_rules(false) do
begin
p :foo => 'bar'
rescue => e
text e.class.name
end
end
begin
p :foo => 'bar'
rescue => e
text e.class.name
end
end
expect(render(wc)).to eq("Fortitude::Errors::InvalidElementAttributesFortitude::Errors::InvalidElementAttributes")
end
it "should allow you to disable enforcement with a block, even across widget boundaries" do
outer = widget_class do
attr_accessor :inner
def content
with_attribute_rules(false) do
widget inner
end
end
end
inner = widget_class_with_content do
p :foo => 'bar'
end
inner_instance = inner.new
outer_instance = outer.new
outer_instance.inner = inner_instance
expect { render(inner_instance) }.to raise_error(Fortitude::Errors::InvalidElementAttributes)
expect(render(outer_instance)).to eq("")
end
it "should allow you to re-enable enforcement with a block" do
wc = widget_class_with_content do
with_attribute_rules(false) do
with_attribute_rules(true) do
p :foo => 'bar'
end
end
end
expect { render(wc) }.to raise_error(Fortitude::Errors::InvalidElementAttributes)
end
it "should allow you to re-enable enforcement with a block, even across widget boundaries" do
outer = widget_class do
attr_accessor :inner
def content
with_attribute_rules(false) do
widget inner
end
end
end
middle = widget_class do
attr_accessor :inner
def content
with_attribute_rules(true) do
widget inner
end
end
end
inner = widget_class_with_content do
p :foo => 'bar'
end
inner_instance = inner.new
middle_instance = middle.new
middle_instance.inner = inner_instance
outer_instance = outer.new
outer_instance.inner = middle_instance
expect { render(inner_instance) }.to raise_error(Fortitude::Errors::InvalidElementAttributes)
expect { render(outer_instance) }.to raise_error(Fortitude::Errors::InvalidElementAttributes)
end
it "should raise an error if you try to enable enforcement with a block in a widget that isn't enforcing in the first place" do
wc = widget_class_with_content(:no_enforcement => true) do
with_attribute_rules(true) do
p :foo => 'bar'
end
end
expect { render(wc) }.to raise_error(ArgumentError)
end
it "should not raise an error if you try to DISable enforcement with a block in a widget that isn't enforcing in the first place" do
wc = widget_class_with_content(:no_enforcement => true) do
p :bar => 'baz'
with_attribute_rules(false) do
p :foo => 'bar'
end
end
expect(render(wc)).to eq("")
end
it "should allow disabling attribute rules on a single element with an option" do
expect(render(widget_class_with_content { p :foo => 'bar', :_fortitude_skip_attribute_rule_enforcement => true })).to eq("")
end
end