require File.dirname(__FILE__) + '/../../spec_helper' describe 'explicit navigation in rails' do require 'simple_navigation/rails_controller_methods' it 'should have enhanced the ActionController after loading the extensions' do ActionController::Base.instance_methods.map {|m| m.to_s}.should include('current_navigation') end describe SimpleNavigation::ControllerMethods do def stub_loading_config SimpleNavigation::Configuration.stub!(:load) end before(:each) do stub_loading_config class TestController class << self def helper_method(*args) @helper_methods = args end def before_filter(*args) @before_filters = args end end end TestController.send(:include, SimpleNavigation::ControllerMethods) @controller = TestController.new end describe 'when being included' do it "should extend the ClassMethods" do @controller.class.should respond_to(:navigation) end it "should include the InstanceMethods" do @controller.should respond_to(:current_navigation) end end describe 'class_methods' do describe 'navigation' do def call_navigation(key1, key2=nil) ActiveSupport::Deprecation.silence do @controller.class_eval do navigation key1, key2 end end end it "should not have an instance-method 'sn_set_navigation' if navigation-method has not been called" do @controller.respond_to?(:sn_set_navigation).should be_false end it 'should create an instance-method "sn_set_navigation" when being called' do call_navigation(:key) @controller.respond_to?(:sn_set_navigation).should be_true end it "the created method should not be public" do call_navigation(:key) @controller.public_methods.map(&:to_sym).should_not include(:sn_set_navigation) end it "the created method should be protected" do call_navigation(:key) @controller.protected_methods.map(&:to_sym).should include(:sn_set_navigation) end it 'the created method should call current_navigation with the specified keys' do call_navigation(:primary, :secondary) @controller.should_receive(:current_navigation).with(:primary, :secondary) @controller.send(:sn_set_navigation) end end end describe 'instance_methods' do describe 'current_navigation' do it "should set the sn_current_navigation_args as specified" do ActiveSupport::Deprecation.silence {@controller.current_navigation(:first)} @controller.instance_variable_get(:@sn_current_navigation_args).should == [:first] end it "should set the sn_current_navigation_args as specified" do ActiveSupport::Deprecation.silence {@controller.current_navigation(:first, :second)} @controller.instance_variable_get(:@sn_current_navigation_args).should == [:first, :second] end end end end describe 'SimpleNavigation module additions' do describe 'handle_explicit_navigation' do def args(*args) SimpleNavigation.stub!(:explicit_navigation_args => args.compact.empty? ? nil : args) end before(:each) do @controller = stub(:controller) @adapter = stub(:adapter, :controller => @controller) SimpleNavigation.stub!(:adapter => @adapter) end context 'with explicit navigation set' do context 'list of navigations' do before(:each) do args :first, :second, :third end it "should set the correct instance var in the controller" do @controller.should_receive(:instance_variable_set).with(:@sn_current_navigation_3, :third) SimpleNavigation.handle_explicit_navigation end end context 'single navigation' do context 'specified key is a valid navigation item' do before(:each) do @primary = stub(:primary, :level_for_item => 2) SimpleNavigation.stub!(:primary_navigation => @primary) args :key end it "should set the correct instance var in the controller" do @controller.should_receive(:instance_variable_set).with(:@sn_current_navigation_2, :key) SimpleNavigation.handle_explicit_navigation end end context 'specified key is an invalid navigation item' do before(:each) do @primary = stub(:primary, :level_for_item => nil) SimpleNavigation.stub!(:primary_navigation => @primary) args :key end it "should raise an ArgumentError" do lambda {SimpleNavigation.handle_explicit_navigation}.should raise_error(ArgumentError) end end end context 'hash with level' do before(:each) do args :level_2 => :key end it "should set the correct instance var in the controller" do @controller.should_receive(:instance_variable_set).with(:@sn_current_navigation_2, :key) SimpleNavigation.handle_explicit_navigation end end context 'hash with multiple_levels' do before(:each) do args :level_2 => :key, :level_1 => :bla end it "should set the correct instance var in the controller" do @controller.should_receive(:instance_variable_set).with(:@sn_current_navigation_2, :key) SimpleNavigation.handle_explicit_navigation end end end context 'without explicit navigation set' do before(:each) do args nil end it "should not set the current_navigation instance var in the controller" do @controller.should_not_receive(:instance_variable_set) SimpleNavigation.handle_explicit_navigation end end end describe 'current_navigation_for' do before(:each) do @controller = stub(:controller) @adapter = stub(:adapter, :controller => @controller) SimpleNavigation.stub!(:adapter => @adapter) end it "should access the correct instance_var in the controller" do @controller.should_receive(:instance_variable_get).with(:@sn_current_navigation_1) SimpleNavigation.current_navigation_for(1) end end end describe SimpleNavigation::Item do before(:each) do @item_container = stub(:item_container, :level => 1) @item = SimpleNavigation::Item.new(@item_container, :my_key, 'name', 'url', {}) end describe 'selected_by_config?' do context 'navigation explicitly set' do it "should return true if current matches key" do SimpleNavigation.stub!(:current_navigation_for => :my_key) @item.should be_selected_by_config end it "should return false if current does not match key" do SimpleNavigation.stub!(:current_navigation_for => :other_key) @item.should_not be_selected_by_config end end context 'navigation not explicitly set' do before(:each) do SimpleNavigation.stub!(:current_navigation_for => nil) end it {@item.should_not be_selected_by_config} end end end describe SimpleNavigation::ItemContainer do describe 'selected_item' do before(:each) do SimpleNavigation.stub!(:current_navigation_for) @item_container = SimpleNavigation::ItemContainer.new @item_1 = stub(:item, :selected? => false) @item_2 = stub(:item, :selected? => false) @item_container.instance_variable_set(:@items, [@item_1, @item_2]) end context 'navigation explicitely set' do before(:each) do @item_container.stub!(:[] => @item_1) end it "should return the explicitely selected item" do @item_container.selected_item.should == @item_1 end end context 'navigation not explicitely set' do before(:each) do @item_container.stub!(:[] => nil) end context 'no item selected' do it "should return nil" do @item_container.selected_item.should be_nil end end context 'one item selected' do before(:each) do @item_1.stub!(:selected? => true) end it "should return the selected item" do @item_container.selected_item.should == @item_1 end end end end end end