require 'spec_helper' describe SimpleNavigation::Item do before(:each) do @item_container = stub(:item_container, :level => 1, :selected_class => nil).as_null_object @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', {}) @adapter = stub(:adapter) SimpleNavigation.stub!(:adapter => @adapter) end describe 'initialize' do context 'subnavigation' do before(:each) do @subnav_container = stub(:subnav_container).as_null_object SimpleNavigation::ItemContainer.stub!(:new => @subnav_container) end context 'block given' do it "should create a new ItemContainer with a level+1" do SimpleNavigation::ItemContainer.should_receive(:new).with(2) SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', {}) {} end it "should call the block" do @subnav_container.should_receive(:test) SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', {}) {|subnav| subnav.test} end end context 'no block given' do context 'items given' do before(:each) do @items = stub(:items) end it "should create a new ItemContainer with a level+1" do SimpleNavigation::ItemContainer.should_receive(:new).with(2) SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', {}, @items) end it "should set the items on the subnav_container" do @subnav_container.should_receive(:items=).with(@items) SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', {}, @items) end end context 'no items given' do it "should not create a new ItemContainer" do SimpleNavigation::ItemContainer.should_not_receive(:new) @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', {}) end end end end context ':method option' do context 'defined' do before(:each) do @options = {:method => :delete} @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', @options) end it 'should set the method as instance_var' do @item.method.should == :delete end it 'should set the html-options without the method' do @item.instance_variable_get(:@html_options).key?(:method).should be_false end end context 'undefined' do it 'should set the instance-var to nil' do @item.method.should be_nil end end end context 'setting class and id on the container' do before(:each) do @options = {:container_class => 'container_class', :container_id => 'container_id'} end it {@item_container.should_receive(:dom_class=).with('container_class')} it {@item_container.should_receive(:dom_id=).with('container_id')} after(:each) do SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', @options) end end context ':highlights_on option' do context 'defined' do before(:each) do @highlights_on = stub(:option) @options = {:highlights_on => @highlights_on} @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', @options) end it 'should set the method as instance_var' do @item.highlights_on.should == @highlights_on end it 'should set the html-options without the method' do @item.instance_variable_get(:@html_options).key?(:highlights_on).should be_false end end context 'undefined' do it 'should set the instance-var to nil' do @item.highlights_on.should be_nil end end end context 'url' do context 'url is a string' do before(:each) do @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', {}) end it {@item.url.should == 'url'} end context 'url is a proc' do before(:each) do @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', Proc.new {"my_" + "url"}, {}) end it {@item.url.should == 'my_url'} end context 'url is nil' do before(:each) do @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', nil, {}) end it {@item.url.should == nil} end context 'url is unspecified' do before(:each) do @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name') end it {@item.url.should == nil} end end context 'optional url and optional options' do context 'when constructed without any optional parameters' do before(:each) do @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name') end it {@item.url.should == nil} it {@item.instance_variable_get(:@html_options).should == {}} end context 'when constructed with only a url' do before(:each) do @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url') end it {@item.url.should == 'url'} it {@item.instance_variable_get(:@html_options).should == {}} end context 'when constructed with only options' do before(:each) do @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', {:option => true}) end it {@item.url.should == nil} it {@item.instance_variable_get(:@html_options).should == {:option => true}} end context 'when constructed with a url and options' do before(:each) do @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', {:option => true}) end it {@item.url.should == 'url'} it {@item.instance_variable_get(:@html_options).should == {:option => true}} end end end describe 'name' do before(:each) do SimpleNavigation.config.stub!(:name_generator => Proc.new {|name| "#{name}"}) end context 'default (generator is applied)' do it {@item.name.should == "name"} end context 'generator is skipped' do it {@item.name(:apply_generator => false).should == 'name'} end end describe 'selected?' do context 'explicitly selected' do before(:each) do @item.stub!(:selected_by_config? => true) end it {@item.should be_selected} it "should not evaluate the subnav or urls" do @item.should_not_receive(:selected_by_subnav?) @item.should_not_receive(:selected_by_condition?) @item.selected? end end context 'not explicitly selected' do before(:each) do @item.stub!(:selected_by_config? => false) end context 'subnav is selected' do before(:each) do @item.stub!(:selected_by_subnav? => true) end it {@item.should be_selected} end context 'subnav is not selected' do before(:each) do @item.stub!(:selected_by_subnav? => false) end context 'selected by condition' do before(:each) do @item.stub!(:selected_by_condition? => true) end it {@item.should be_selected} end context 'not selected by condition' do before(:each) do @item.stub!(:selected_by_condition? => false) end it {@item.should_not be_selected} end end end end describe 'selected_class' do context 'selected_class is defined in context' do before(:each) do @item_container = stub(:item_container, :level => 1, :selected_class => 'context_defined').as_null_object @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', {}) @item.stub!(:selected? => true) end it {@item.instance_eval {selected_class.should == 'context_defined'}} end context 'item is selected' do before(:each) do @item.stub!(:selected? => true) end it {@item.instance_eval {selected_class.should == 'selected'}} end context 'item is not selected' do before(:each) do @item.stub!(:selected? => false) end it {@item.instance_eval {selected_class.should == nil}} end end describe 'html_options' do describe 'class' do context 'with classes defined in options' do before(:each) do @options = {:class => 'my_class'} @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', @options) end context 'with item selected' do before(:each) do @item.stub!(:selected? => true, :selected_by_condition? => true) end it {@item.html_options[:class].should == 'my_class selected simple-navigation-active-leaf'} end context 'with item not selected' do before(:each) do @item.stub!(:selected? => false, :selected_by_condition? => false) end it {@item.html_options[:class].should == 'my_class'} end end context 'without classes in options' do before(:each) do @options = {} @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', @options) end context 'with item selected' do before(:each) do @item.stub!(:selected? => true, :selected_by_condition? => true) end it {@item.html_options[:class].should == 'selected simple-navigation-active-leaf'} end context 'with item not selected' do before(:each) do @item.stub!(:selected? => false, :selected_by_condition? => false) end it {@item.html_options[:class].should be_blank} end end end describe 'id' do context 'with autogenerate_item_ids == true' do before(:each) do @item.stub!(:autogenerate_item_ids? => true) @item.stub!(:selected? => false, :selected_by_condition? => false) end context 'with id defined in options' do before(:each) do @item.html_options = {:id => 'my_id'} end it {@item.html_options[:id].should == 'my_id'} end context 'with no id defined in options (using default id)' do before(:each) do @item.html_options = {} end it {@item.html_options[:id].should == 'my_key'} end end context 'with autogenerate_item_ids == false' do before(:each) do @item.stub!(:autogenerate_item_ids? => false) @item.stub!(:selected? => false, :selected_by_condition? => false) end context 'with id defined in options' do before(:each) do @item.html_options = {:id => 'my_id'} end it {@item.html_options[:id].should == 'my_id'} end context 'with no id definied in options (using default id)' do before(:each) do @item.html_options = {} end it {@item.html_options[:id].should be_nil} end end end end describe 'selected_by_subnav?' do context 'item has subnav' do before(:each) do @sub_navigation = stub(:sub_navigation) @item.stub!(:sub_navigation => @sub_navigation) end it "should return true if subnav is selected" do @sub_navigation.stub!(:selected? => true, :selected_by_condition? => true) @item.should be_selected_by_subnav end it "should return false if subnav is not selected" do @sub_navigation.stub!(:selected? => false, :selected_by_condition? => true) @item.should_not be_selected_by_subnav end end context 'item does not have subnav' do before(:each) do @item.stub!(:sub_navigation => @sub_navigation) end it {@item.should_not be_selected_by_subnav} end end describe 'selected_by_condition?' do context ':highlights_on option is set' do before(:each) do @item.stub!(:highlights_on => /^\/current/) SimpleNavigation.stub!(:request_uri => '/current_url') end it "should not check for autohighlighting" do @item.should_not_receive(:auto_highlight?) @item.send(:selected_by_condition?) end context ':highlights_on is a regexp' do context 'regexp matches current_url' do it {@item.send(:selected_by_condition?).should be_true} end context 'regexp does not match current_url' do before(:each) do @item.stub!(:highlights_on => /^\/no_match/) end it {@item.send(:selected_by_condition?).should be_false} end end context ':highlights_on is a lambda' do context 'truthy lambda results in selection' do before(:each) do @item.stub!(:highlights_on => lambda{true}) end it {@item.send(:selected_by_condition?).should be_true} end context 'falsey lambda results in no selection' do before(:each) do @item.stub!(:highlights_on => lambda{false}) end it {@item.send(:selected_by_condition?).should be_false} end end context ':highlights_on is :subpath' do before(:each) do @item.stub!(:url => '/resources') @item.stub!(:highlights_on => :subpath) end context 'we are in a route beginning with this item path' do before(:each) do SimpleNavigation.stub!(:request_uri => '/resources/id') end it {@item.send(:selected_by_condition?).should be_true} end context 'we are in a route that has a similar name' do before(:each) do SimpleNavigation.stub!(:request_uri => '/resources_group/id') end it {@item.send(:selected_by_condition?).should be_false} end context 'we are in a route not beginning with this item path' do before(:each) do SimpleNavigation.stub!(:request_uri => '/another_resource/id') end it {@item.send(:selected_by_condition?).should be_false} end end context ':highlights_on is not a regexp or a proc' do before(:each) do @item.stub!(:highlights_on => "not a regexp") end it "should raise an error" do lambda {@item.send(:selected_by_condition?).should raise_error(ArgumentError)} end end end context ':highlights_on option is not set' do before(:each) do @item.stub!(:highlights_on => nil) end it "should check for autohighlighting" do @item.should_receive(:auto_highlight?) @item.send(:selected_by_condition?) end end context 'auto_highlight is turned on' do before(:each) do @item.stub!(:auto_highlight? => true) end context 'root path matches' do before(:each) do @item.stub!(:root_path_match? => true) end it {@item.send(:selected_by_condition?).should be_true} end context 'root path does not match' do before(:each) do @item.stub!(:root_path_match? => false) end context 'current request url matches url' do before(:each) do @adapter.stub!(:current_page? => true) end it "should test with the item's url" do @adapter.should_receive(:current_page?).with('url') @item.send(:selected_by_condition?) end it "should remove anchors before testing the item's url" do @item.stub!(:url => 'url#anchor') @adapter.should_receive(:current_page?).with('url') @item.send(:selected_by_condition?) end it "should not be queried when url is nil" do @item.stub!(:url => nil) @adapter.should_not_receive(:current_page?) @item.send(:selected_by_condition?) end it {@item.send(:selected_by_condition?).should be_true} end context 'no match' do before(:each) do @adapter.stub!(:current_page? => false) end it {@item.send(:selected_by_condition?).should be_false} end end end context 'auto_highlight is turned off' do before(:each) do @item.stub!(:auto_highlight? => false) end it {@item.send(:selected_by_condition?).should be_false} end end describe 'root_path_match?' do it "should match if both url == /" do @adapter.stub!(:request_path => '/') @item.stub!(:url => '/') @item.send(:root_path_match?).should be_true end it "should not match if item url is not /" do @adapter.stub(:request_path => '/') @item.stub!(:url => '/bla') @item.send(:root_path_match?).should be_false end it "should not match if request url is not /" do @adapter.stub(:request_path => '/bla') @item.stub!(:url => '/') @item.send(:root_path_match?).should be_false end it "should not match if urls do not match" do @adapter.stub(:request_path => 'bla') @item.stub!(:url => '/bli') @item.send(:root_path_match?).should be_false end it "should not match if url is nil" do @adapter.stub(:request_path => 'bla') @item.stub!(:url => nil) @item.send(:root_path_match?).should be_false end end describe 'auto_highlight?' do before(:each) do @global = stub(:config) SimpleNavigation.stub!(:config => @global) end context 'global auto_highlight on' do before(:each) do @global.stub!(:auto_highlight => true) end context 'container auto_highlight on' do before(:each) do @item_container.stub!(:auto_highlight => true) end it {@item.send(:auto_highlight?).should be_true} end context 'container auto_highlight off' do before(:each) do @item_container.stub!(:auto_highlight => false) end it {@item.send(:auto_highlight?).should be_false} end end context 'global auto_highlight off' do before(:each) do @global.stub!(:auto_highlight => false) end context 'container auto_highlight on' do before(:each) do @item_container.stub!(:auto_highlight => true) end it {@item.send(:auto_highlight?).should be_false} end context 'container auto_highlight off' do before(:each) do @item_container.stub!(:auto_highlight => false) end it {@item.send(:auto_highlight?).should be_false} end end end describe 'autogenerated_item_id' do context 'calls' do before(:each) do @id_generator = stub(:id_generator) SimpleNavigation.config.stub!(:id_generator => @id_generator) end it "should call the configured generator with the key as param" do @id_generator.should_receive(:call).with(:my_key) @item.send(:autogenerated_item_id) end end context 'default generator' do it {@item.send(:autogenerated_item_id).should == 'my_key'} end end end