require 'spec_helper'
module Deface
describe Override do
include_context "mock Rails.application"
before(:each) do
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :replace => "h1", :text => "
Argh!
")
end
it "should return correct action" do
Deface::Override.actions.each do |action|
Rails.application.config.deface.overrides.all.clear
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", action => "h1", :text => "Argh!
")
expect(@override.action).to eq(action)
end
end
it "should have a sources method" do
expect(Deface::DEFAULT_SOURCES.map(&:to_sym)).to include(:text)
end
it "should return correct selector" do
expect(@override.selector).to eq("h1")
end
it "should set default :updated_at" do
expect(@override.args[:updated_at]).not_to be_nil
end
describe "#original_source" do
it "should return nil with not specified" do
expect(@override.original_source).to be_nil
end
it "should return parsed nokogiri document when present" do
@original = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :replace => "h1", :text => "Argh!
", :original => "<%= something %>
")
expect(@original.original_source).to be_an_instance_of Nokogiri::HTML::DocumentFragment
if RUBY_PLATFORM == 'java'
expect(@original.original_source.to_s).to eq(" something
")
else
expect(@original.original_source.to_s).to eq(" something
")
end
end
end
describe "#validate_original when :original is not present" do
before(:each) do
@original = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :replace => "h1", :text => "Argh!
")
end
it "should warn but not validate" do
expect(Rails.logger).to receive(:info).once
expect(@override.validate_original("this gets ignored
")).to be_nil
end
end
describe "#validate_original when :original is present" do
before(:each) do
@original = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :replace => "h1", :text => "Argh!
", :original => "<%= something %>
")
end
it "should return true when input contains similar (ignoring whitespace)" do
if RUBY_PLATFORM == 'java'
expect( @original.validate_original(" something
") ).to eql true
expect( @original.validate_original("something\n
") ).to eql true
else
expect( @original.validate_original(" something
") ).to eql true
expect( @original.validate_original("something\n
") ).to eql true
end
end
it "should return true when input is an array" do
if RUBY_PLATFORM == 'java'
expect( @original.validate_original([" something ","
"]) ).to eql true
expect( @original.validate_original(["something\n","
"]) ).to eql true
else
expect( @original.validate_original([" something","
"]) ).to eql true
expect( @original.validate_original(["something\n","
"]) ).to eql true
end
end
it "should return false when and input contains different string" do
expect( @original.validate_original("wrong") ).to eql false
end
it "should return false with input being an array and is a different string" do
expect( @original.validate_original(["wrong", "again"]) ).to eql false
end
end
describe "#new" do
it "should increase all#size by 1" do
expect {
Deface::Override.new(:virtual_path => "posts/new", :name => "Posts#new", :replace => "h1", :text => "argh!
")
}.to change{Deface::Override.all.size}.by(1)
end
it "should default :name when none is given" do
override = Deface::Override.new(:virtual_path => "posts/new", :replace => "h1", :text => "Derp!
")
expect(override.name).not_to be_empty
end
it "should default :name to caller's file name and a line number" do
override = Deface::Override.new(:virtual_path => "posts/new", :replace => "h1", :text => "Derp!
")
expect(override.name).to match Regexp.new("#{Regexp.escape(File.basename(__FILE__, '.rb'))}_\\d+")
end
it "should use :name argument when given" do
name = "Posts#new"
override = Deface::Override.new(:virtual_path => "posts/new", :name => name, :replace => "h1", :text => "Derp!
")
expect(override.name).to eq(name)
end
end
describe "with :text" do
before(:each) do
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :replace => "h1", :text => "\">Argh!
")
end
it "should return un-convert text as source" do
expect(@override.source).to eq("\">Argh!
")
expect(@override.source_argument).to eq(:text)
end
end
describe "with :erb" do
before(:each) do
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :replace => "h1", :erb => "\">Argh!
")
end
it "should return un-convert text as source" do
expect(@override.source).to eq("\">Argh!
")
expect(@override.source_argument).to eq(:erb)
end
end
describe "with :haml" do
before(:each) do
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :replace => "h1",
:haml => %q{%strong{:class => "erb", :id => "message"}= 'Hello, World!'})
end
it "should return erb converted from haml as source" do
expect(@override.source).to eq("<%= 'Hello, World!' %>\n")
expect(@override.source_argument).to eq(:haml)
end
end
describe "with :slim" do
before(:each) do
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :replace => "h1",
:slim => %q{strong class="erb" id="message"= 'Hello, World!'})
end
it "should return erb converted from slim as source" do
expect(@override.source).to eq("<%= ::Temple::Utils.escape_html_safe(('Hello, World!')) %>\n")
expect(@override.source_argument).to eq(:slim)
end
end
describe "with :partial containing erb" do
before(:each) do
#stub view paths to be local spec/assets directory
allow(ActionController::Base).to receive(:view_paths).and_return([File.join(File.dirname(__FILE__), '..', "assets")])
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :replace => "h1", :partial => "shared/post")
end
it "should return un-convert partial contents as source" do
expect(@override.source).to eq("I'm from shared/post partial
\n<%= \"And I've got ERB\" %>\n")
expect(@override.source_argument).to eq(:partial)
end
end
describe "with :template" do
before(:each) do
#stub view paths to be local spec/assets directory
allow(ActionController::Base).to receive(:view_paths).and_return([File.join(File.dirname(__FILE__), '..', "assets")])
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :replace => "h1", :template => "shared/person")
end
it "should return un-convert template contents as source" do
expect(@override.source).to eq("I'm from shared/person template
\n<%= \"I've got ERB too\" %>\n")
expect(@override.source_argument).to eq(:template)
end
end
describe "with :copy" do
let(:parsed) { Deface::Parser.convert("Manage Posts
<%= some_method %>") }
before(:each) do
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :insert_after => "h1", :copy => "h1")
allow(@override).to receive(:parsed_document).and_return(parsed)
end
it "should not change original parsed source" do
@override.source
if RUBY_PLATFORM == 'java'
expect(parsed.to_s.gsub(/\n/,'')).to eq("Manage Posts
some_method ")
else
expect(parsed.to_s.gsub(/\n/,'')).to eq("Manage Posts
some_method ")
end
expect(@override.source_argument).to eq(:copy)
end
it "should return copy of content from source document" do
expect(@override.source.to_s.strip).to eq("Manage Posts
")
end
it "should return unescaped content for source document" do
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :insert_after => "h1", :copy => "erb[loud]:contains('some_method')")
allow(@override).to receive(:parsed_document).and_return(parsed)
expect(@override.source).to eq("<%= some_method %>")
end
end
describe "with :copy using :start and :end" do
let(:parsed) { Deface::Parser.convert("World
<% if true %>True that!
<% end %>Hello
") }
before(:each) do
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :insert_after => "h1",
:copy => {:start => "erb:contains('if true')", :end => "erb:contains('end')"})
allow(@override).to receive(:parsed_document).and_return(parsed)
end
it "should not change original parsed source" do
@override.source
if RUBY_PLATFORM == 'java'
expect(parsed.to_s.gsub(/\n/,'')).to eq("World
if true True that!
end Hello
")
else
expect(parsed.to_s.gsub(/\n/,'')).to eq("World
if true True that!
end Hello
")
end
expect(@override.source_argument).to eq(:copy)
end
it "should return copy of content from source document" do
expect(@override.source).to eq("<% if true %>True that!
<% end %>")
end
end
describe "with :cut" do
let(:parsed) { Deface::Parser.convert("Manage Posts
<%= some_method %>") }
before(:each) do
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :insert_after => "h1", :cut => "h1")
allow(@override).to receive(:parsed_document).and_return(parsed)
end
it "should remove cut element from original parsed source" do
@override.source
if RUBY_PLATFORM == 'java'
expect(parsed.to_s.gsub(/\n/,'')).to eq(" some_method
")
else
expect(parsed.to_s.gsub(/\n/,'')).to eq(" some_method
")
end
expect(@override.source_argument).to eq(:cut)
end
it "should remove and return content from source document" do
expect(@override.source).to eq("Manage Posts
")
end
it "should return unescaped content for source document" do
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :insert_after => "h1", :cut => "erb[loud]:contains('some_method')")
allow(@override).to receive(:parsed_document).and_return(parsed)
expect(@override.source).to eq("<%= some_method %>")
end
end
describe "with :cut using :start and :end" do
let(:parsed) { Deface::Parser.convert("World
<% if true %>True that!
<% end %><%= hello %>") }
before(:each) do
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :insert_after => "h1",
:cut => {:start => "erb:contains('if true')", :end => "erb:contains('end')"})
allow(@override).to receive(:parsed_document).and_return(parsed)
end
it "should remove cut element from original parsed source" do
@override.source
if RUBY_PLATFORM == 'java'
expect(parsed.to_s.gsub(/\n/,'')).to eq("World
hello ")
else
expect(parsed.to_s.gsub(/\n/,'')).to eq("World
hello ")
end
expect(@override.source_argument).to eq(:cut)
end
it "should return copy of content from source document" do
expect(@override.source).to eq("<% if true %>True that!
<% end %>")
end
end
describe "with block" do
before(:each) do
#stub view paths to be local spec/assets directory
allow(ActionController::Base).to receive(:view_paths).and_return([File.join(File.dirname(__FILE__), '..', "assets")])
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :replace => "h1") do
"This is replacement text for the h1"
end
end
it "should set source to block content" do
expect(@override.source).to eq("This is replacement text for the h1")
end
end
describe "with :namespaced" do
before(:each) do
Deface::Override.current_railtie = 'SpreeEngine'
@override = Deface::Override.new(:virtual_path => 'sample_path', :name => 'sample_name', :replace => 'h1', :namespaced => true)
end
it "should namespace the override's name" do
expect(@override.name).to eq('spree_engine_sample_name')
end
end
describe "with global namespaced option set to true" do
before(:each) do
Deface::Override.current_railtie = 'SpreeEngine'
Rails.application.config.deface.namespaced = true
@override = Deface::Override.new(:virtual_path => 'sample_path', :name => 'sample_name', :replace => 'h1')
end
it "should namespace the override's name" do
expect(@override.name).to eq('spree_engine_sample_name')
end
end
describe "#source_element" do
before(:each) do
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :replace => "h1", :text => "<%= method :opt => 'x' & 'y' %>")
end
it "should return escaped source" do
expect(@override.source_element).to be_an_instance_of Nokogiri::HTML::DocumentFragment
if RUBY_PLATFORM == 'java'
source = " method :opt => 'x' & 'y' "
expect(@override.source_element.to_s).to eq(source)
#do it twice to ensure it doesn't change as it's destructive
expect(@override.source_element.to_s).to eq(source)
else
source = " method :opt => 'x' & 'y' "
expect(@override.source_element.to_s).to eq(source)
#do it twice to ensure it doesn't change as it's destructive
expect(@override.source_element.to_s).to eq(source)
end
end
end
describe "when redefining an override without changing action or source type" do
before(:each) do
Rails.application.config.deface.overrides.all.clear
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :text => "Argh!
", :replace => "h1")
expect {
@replacement = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :text => "Arrrr!
")
}.to change{Rails.application.config.deface.overrides.all.size}.by(0)
end
it "should return new source" do
expect(@replacement.source).not_to eq("Argh!
")
expect(@replacement.source).to eq("Arrrr!
")
end
end
describe "when redefining an override when changing action" do
before(:each) do
Rails.application.config.deface.overrides.all.clear
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :replace => "h1")
expect {
@replacement = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :insert_after => "h1")
}.to change{Rails.application.config.deface.overrides.all.size}.by(0)
end
it "should return new action" do
expect(@replacement.action).to eq(:insert_after)
end
it "should remove old action" do
expect( @replacement.args.has_key?(:replace)).to eql false
end
end
describe "when redefining an override when changing source type" do
before(:each) do
#stub view paths to be local spec/assets directory
allow(ActionController::Base).to receive(:view_paths).and_return([File.join(File.dirname(__FILE__), '..', "assets")])
Rails.application.config.deface.overrides.all.clear
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :partial => "shared/post", :replace => "h1", :text => "I'm text")
expect {
@replacement = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :erb => "I do be a pirate!
")
}.to change{Rails.application.config.deface.overrides.all.size}.by(0)
end
it "should return new source" do
expect(@override.source).to eq("I do be a pirate!
")
end
end
describe "#sequence" do
it "should calculate correct after sequences" do
@third = Deface::Override.new(:virtual_path => "posts/index", :name => "third", :insert_after => "li:contains('second')", :text => "third", :sequence => {:after => "second"})
@second = Deface::Override.new(:virtual_path => "posts/index", :name => "second", :insert_after => "li", :text => "second", :sequence => {:after => "first"})
@first = Deface::Override.new(:virtual_path => "posts/index", :name => "first", :replace => "li", :text => "first")
expect(@third.sequence).to eq(102)
expect(@second.sequence).to eq(101)
expect(@first.sequence).to eq(100)
end
it "should calculate correct before sequences" do
@second = Deface::Override.new(:virtual_path => "posts/index", :name => "second", :insert_after => "li", :text => "second", :sequence => 99)
@first = Deface::Override.new(:virtual_path => "posts/index", :name => "first", :replace => "li", :text => "first", :sequence => {:before => "second"})
expect(@second.sequence).to eq(99)
expect(@first.sequence).to eq(98)
end
it "should calculate correct sequences with invalid hash" do
@second = Deface::Override.new(:virtual_path => "posts/index", :name => "second", :insert_after => "li", :text => "second", :sequence => {})
@first = Deface::Override.new(:virtual_path => "posts/show", :name => "first", :replace => "li", :text => "first", :sequence => {:before => "second"})
expect(@second.sequence).to eq(100)
expect(@first.sequence).to eq(100)
end
end
describe "#end_selector" do
it "should return nil when closing_selector is not defined" do
expect(@override.end_selector).to be_nil
end
it "should return nil when closing_selector is an empty string" do
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :replace => "h1", :closing_selector => "", :text => "Argh!
")
expect(@override.end_selector).to be_nil
end
it "should return nil when closing_selector is nil" do
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :replace => "h1", :closing_selector => nil, :text => "Argh!
")
expect(@override.end_selector).to be_nil
end
it "should return closing_selector is present" do
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :replace => "h1", :closing_selector => "h4", :text => "Argh!
")
expect(@override.end_selector).to eq("h4")
end
end
describe "#touch" do
it "should change the overrides :updated_at value" do
before_touch = @override.args[:updated_at]
allow(Time.zone).to receive(:now).and_return(Time.parse('2006-08-24'))
@override.touch
expect(@override.args[:updated_at]).not_to eq(before_touch)
end
end
describe "#digest" do
before do
Deface::Override.all.clear
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :replace => "h1", :text => "Argh!
")
@digest = @override.digest.clone
end
it "should return hex digest based on override's args" do
expect(@override.digest).to match(/[a-f0-9]{32}/)
end
it "should change the digest when any args change" do
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :replace => "h2", :text => "Argh!
")
expect(@override.digest).not_to eq(@digest)
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :replace => "h1", :text => "Argh!
")
expect(@override.digest).to eq(@digest)
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :replace => "h2", :text => "I'm a pirate!
")
expect(@override.digest).not_to eq(@digest)
end
end
describe "self#digest" do
before do
Deface::Override.all.clear
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :replace => "h1", :text => "Argh!
")
@second = Deface::Override.new(:virtual_path => "posts/index", :name => "second", :insert_after => "p", :text => "this is erb?
")
@digest = Deface::Override.digest(:virtual_path => "posts/index")
end
it "should return hex digest based on all applicable overrides" do
expect(Deface::Override.digest(:virtual_path => "posts/index")).to match(/[a-f0-9]{32}/)
end
it "should change the digest when any args change for any override" do
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :replace => "h2", :text => "Argh!
")
expect(Deface::Override.digest(:virtual_path => "posts/index")).not_to eq(@digest)
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :replace => "h1", :text => "Argh!
")
expect(Deface::Override.digest(:virtual_path => "posts/index")).to eq(@digest)
@second = Deface::Override.new(:virtual_path => "posts/index", :name => "2nd", :insert_after => "p", :text => "this is erb?
")
expect(Deface::Override.digest(:virtual_path => "posts/index")).not_to eq(@digest)
end
it "should change the digest when overrides are removed / added" do
Deface::Override.all.clear
@new_digest = Deface::Override.digest(:virtual_path => "posts/index")
expect(@new_digest).not_to eq(@digest)
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :replace => "h1", :text => "Argh!
")
expect(Deface::Override.digest(:virtual_path => "posts/index")).not_to eq(@new_digest)
end
end
describe "#expire_compiled_template" do
it "should remove compiled method when method name matches virtual path but not digest" do
instance_methods_count = ActionView::Base.instance_methods.size
ActionView::Base.class_eval do
def _e235fa404c3c2281d4f6791162b1c638_posts_index_123123123
true #not a real method
end
def _f34556de606cec51d4f6791163fab456_posts_edit_123123123
true #not a real method
end
end
expect(ActionView::Base.instance_methods.size).to eq(instance_methods_count + 2)
@override.send(:expire_compiled_template)
expect(ActionView::Base.instance_methods.size).to eq(instance_methods_count + 1)
end
it "should not remove compiled method when virtual path and digest matach" do
instance_methods_count = ActionView::Base.instance_methods.size
ActionView::Base.class_eval do
def _e235fa404c3c2281d4f6791162b1c638_posts_index_123123123
true #not a real method
end
end
expect(Deface::Override).to receive(:digest).and_return('e235fa404c3c2281d4f6791162b1c638')
expect(ActionView::Base.instance_methods.size).to eq(instance_methods_count + 1)
@override.send(:expire_compiled_template)
expect(ActionView::Base.instance_methods.size).to eq(instance_methods_count + 1)
end
end
end
end