Skip to content

Commit

Permalink
Isolated MenuItem spec's from global rails app
Browse files Browse the repository at this point in the history
  • Loading branch information
gregbell committed Jan 9, 2012
1 parent 67558e1 commit da8d0d3
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 37 deletions.
42 changes: 25 additions & 17 deletions lib/active_admin/menu_item.rb
Original file line number Diff line number Diff line change
@@ -1,73 +1,81 @@
module ActiveAdmin
class MenuItem

# Use this to get to the routes
include Rails.application.routes.url_helpers



# Generates a route using the rails application url helpers
#
# @param [Symbol] named_route
#
# @returns [String] The generated route
def self.generate_url(named_route)
Rails.application.routes.url_helpers.send(named_route)
end

attr_accessor :name, :url, :priority, :parent, :display_if_block

def initialize(name, url, priority = 10, options = {})
@name, @url, @priority = name, url, priority
@children = []
@cached_url = {} # Stores the cached url in a hash to allow us to change it and still cache it

@display_if_block = options.delete(:if)

yield(self) if block_given? # Builder style syntax
end

def add(name, url, priority=10, options = {}, &block)
item = MenuItem.new(name, url, priority, options, &block)
item.parent = self
@children << item
end
end

def children
@children.sort
end

def parent?
!parent.nil?
end

def dom_id
name.downcase.gsub( " ", '_' ).gsub( /[^a-z0-9_]/, '' )
end

def url
case @url
when Symbol
generated = send(@url) # Call the named route
generated = self.class.generate_url(@url) # Call the named route
else
generated = @url
end
@cached_url[@url] ||= generated
end

# Returns an array of the ancestory of this menu item
# The first item is the immediate parent fo the item
def ancestors
return [] unless parent?
[parent, parent.ancestors].flatten
end

# Returns the child item with the name passed in
# @blog_menu["Create New"] => <#MenuItem @name="Create New" >
def [](name)
@children.find{ |i| i.name == name }
end

def <=>(other)
result = priority <=> other.priority
result = name <=> other.name if result == 0
result
end

# Returns the display if block. If the block was not explicitly defined
# a default block always returning true will be returned.
def display_if_block
@display_if_block || lambda { |_| true }
end

end

end
end
45 changes: 25 additions & 20 deletions spec/unit/menu_item_spec.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'spec_helper'
require 'spec_helper_without_rails'
require 'active_admin/menu_item'

module ActiveAdmin
describe MenuItem do
Expand All @@ -7,27 +8,27 @@ module ActiveAdmin
item = MenuItem.new("Dashboard", "/admin")
item.name.should == "Dashboard"
end

it "should have a url" do
item = MenuItem.new("Dashboard", "/admin")
item.url.should == "/admin"
end

it "should have a priority of 10 by default" do
item = MenuItem.new("Dashboard", "/admin")
item.priority.should == 10
end

it "should accept an optional options hash" do
item = MenuItem.new("Dashboard", "/admin", 10, :if => lambda{ logged_in? } )
end

it "should have a display if block" do
block = lambda{ logged_in? }
item = MenuItem.new("Dashboard", "/admin", 10, :if => block )
item.display_if_block.should == block
end

it "should have a default display if block always returning true" do
item = MenuItem.new("Dashboard", "/admin")
item.display_if_block.should be_instance_of(Proc)
Expand All @@ -36,28 +37,32 @@ module ActiveAdmin

describe "url generation and caching" do
it "should generate a url if it is a symbol" do
MenuItem.new("Posts", :admin_posts_path).url.should == "/admin/posts"
item = MenuItem.new("Posts", :admin_posts_path)
MenuItem.should_receive(:generate_url).with(:admin_posts_path).
and_return("/admin/posts")

item.url.should == "/admin/posts"
end

it "should generate a url if it is a string" do
MenuItem.new("Posts", "/admin/posts").url.should == "/admin/posts"
end
end

context "with no children" do
it "should be empty" do
item = MenuItem.new("Blog", "/admin/blog")
item.children.should == []
end

it "should accept new children" do
item = MenuItem.new("Blog", "/admin/blog")
item.add "Dashboard", "/admin"
item.children.first.should be_an_instance_of(MenuItem)
item.children.first.name.should == "Dashboard"
end
end

context "with many children" do
let(:item) do
i = MenuItem.new("Dashboard", "/admin")
Expand All @@ -68,24 +73,24 @@ module ActiveAdmin
i.add "Analytics", "/", 44
i
end

it "should give access to the menu item as an array" do
item['Blog'].name.should == 'Blog'
end

it "should sort items based on priority and name" do
item.children[0].name.should == 'Users'
item.children[1].name.should == 'Settings'
item.children[2].name.should == 'Blog'
item.children[3].name.should == 'Cars'
item.children[4].name.should == 'Analytics'
end

it "children should hold a reference to their parent" do
item["Blog"].parent.should == item
end
end

describe "building children using block syntax" do
let(:item) do
MenuItem.new("Blog", "/") do |blog|
Expand All @@ -95,25 +100,25 @@ module ActiveAdmin
end
end
end

it "should have 2 children" do
item.children.size.should == 2
end

it "should have sub-sub items" do
item["Comments"]["Approved"].name.should == 'Approved'
end
end

describe "accessing ancestory" do
let(:item){ MenuItem.new "Blog", "/blog" }

context "with no parent" do
it "should return an empty array" do
item.ancestors.should == []
end
end

context "with one parent" do
let(:sub_item) do
item.add "Create New", "/blog/new"
Expand All @@ -123,7 +128,7 @@ module ActiveAdmin
sub_item.ancestors.should == [item]
end
end

context "with many parents" do
before(:each) do
item.add "C1", "/c1" do |c1|
Expand Down

0 comments on commit da8d0d3

Please sign in to comment.