require 'spec_helper' require "active_support/core_ext/hash" require "active_support/core_ext/object" require 'datagrid/renderer' describe Datagrid::Helper do subject do template = ActionView::Base.new allow(template).to receive(:protect_against_forgery?).and_return(false) template.view_paths << File.expand_path("../../../app/views", __FILE__) template.view_paths << File.expand_path("../../support/test_partials", __FILE__) template end before(:each) do allow(subject).to receive(:params).and_return({}) allow(subject).to receive(:url_for) do |options| options.is_a?(String) ? options : ["/location", options.to_param.presence].compact.join('?') end end let(:group) { Group.create!(:name => "Pop") } let!(:entry) { Entry.create!( :group => group, :name => "Star", :disabled => false, :confirmed => false, :category => "first" ) } let(:grid) { SimpleReport.new } context "when grid has no records" do let(:grid) do test_report do scope { Entry.where("1 != 1") } column(:id) end end it "should show an empty table with dashes" do datagrid_table = subject.datagrid_table(grid) expect(datagrid_table).to match_css_pattern( "table.datagrid tr td.noresults" => 1 ) expect(datagrid_table).to include("——") end end describe ".datagrid_table" do it "should have grid class as html class on table" do expect(subject.datagrid_table(grid)).to match_css_pattern( "table.datagrid.simple_report" => 1 ) end it "should have namespaced grid class as html class on table" do module ::Ns23 class TestGrid include Datagrid scope { Entry } column(:id) end end expect(subject.datagrid_table(::Ns23::TestGrid.new)).to match_css_pattern( "table.datagrid.ns23_test_grid" => 1 ) end it "should return data table html" do datagrid_table = subject.datagrid_table(grid) expect(datagrid_table).to match_css_pattern({ "table.datagrid tr th.group div.order" => 1, "table.datagrid tr th.group" => /Group.*/, "table.datagrid tr th.name div.order" => 1, "table.datagrid tr th.name" => /Name.*/, "table.datagrid tr td.group" => "Pop", "table.datagrid tr td.name" => "Star" }) end it "should support giving assets explicitly" do Entry.create!(entry.attributes) datagrid_table = subject.datagrid_table(grid, [entry]) expect(datagrid_table).to match_css_pattern({ "table.datagrid tr th.group div.order" => 1, "table.datagrid tr th.group" => /Group.*/, "table.datagrid tr th.name div.order" => 1, "table.datagrid tr th.name" => /Name.*/, "table.datagrid tr td.group" => "Pop", "table.datagrid tr td.name" => "Star" }) end it "should support no order given" do expect(subject.datagrid_table(grid, [entry], :order => false)).to match_css_pattern("table.datagrid th .order" => 0) end it "should support columns option" do expect(subject.datagrid_table(grid, [entry], :columns => [:name])).to match_css_pattern( "table.datagrid th.name" => 1, "table.datagrid td.name" => 1, "table.datagrid th.group" => 0, "table.datagrid td.group" => 0 ) end context "with column_names attribute" do let(:grid) do test_report(:column_names => "name") do scope { Entry } column(:name) column(:category) end end it "should output only given column names" do expect(subject.datagrid_table(grid, [entry])).to match_css_pattern( "table.datagrid th.name" => 1, "table.datagrid td.name" => 1, "table.datagrid th.category" => 0, "table.datagrid td.category" => 0 ) end end context "when grid has no columns" do let(:grid) do test_report do scope {Entry} end end it "should render no_columns message" do expect(subject.datagrid_table(grid, [entry])).to equal_to_dom("No columns selected") end end context 'with partials attribute' do let(:grid) do test_report do scope { Entry } column(:name) column(:category) end end it 'renders namespaced table partial' do rendered_partial = subject.datagrid_table(grid, [entry], { :partials => 'client/datagrid' }) expect(rendered_partial).to include 'Namespaced table partial.' expect(rendered_partial).to include 'Namespaced row partial.' expect(rendered_partial).to include 'Namespaced head partial.' expect(rendered_partial).to include 'Namespaced order_for partial.' end end context "when scope is enumerator" do let(:grid) do test_report do scope { ['a', 'b'].to_enum } column(:name) do |value| value end end end it "should render table" do expect(subject.datagrid_table(grid)).to match_css_pattern( "table.datagrid th.name" => 1, "table.datagrid td.name" => 2, ) end end context "when scope is lazy enumerator" do before(:each) do pending("not supported by ruby < 2.0") if RUBY_VERSION < '2.0' end let(:grid) do test_report do scope { ['a', 'b'].lazy } column(:name) do |value| value end end end it "should render table" do expect(subject.datagrid_table(grid)).to match_css_pattern( "table.datagrid th.name" => 1, "table.datagrid td.name" => 2, ) end end end describe ".datagrid_rows" do it "should support urls" do rp = test_report do scope { Entry } column(:name, :url => lambda {|model| model.name}) end expect(subject.datagrid_rows(rp, [entry])).to match_css_pattern( "tr td.name a[href=Star]" => "Star" ) end it "should support conditional urls" do rp = test_report do scope { Entry } column(:name, :url => lambda {|model| false}) end expect(subject.datagrid_rows(rp, [entry])).to match_css_pattern( "tr td.name" => "Star" ) end it "should add ordering classes to column" do rp = test_report(:order => :name) do scope { Entry } column(:name) end expect(subject.datagrid_rows(rp, [entry])).to match_css_pattern( "tr td.name.ordered.asc" => "Star" ) end it "should add ordering classes to column" do rp = test_report(:order => :name, :descending => true) do scope { Entry } column(:name) end expect(subject.datagrid_rows(rp, [entry])).to match_css_pattern( "tr td.name.ordered.desc" => "Star" ) end it "should render html columns" do rp = test_report do scope { Entry } column(:name, :html => true) do |model| content_tag(:span, model.name) end end expect(subject.datagrid_rows(rp, [entry])).to match_css_pattern( "tr td.name span" => "Star" ) end it "should render argument-based html columns" do rp = test_report do scope { Entry } column(:name, :html => lambda {|data| content_tag :h1, data}) end expect(subject.datagrid_rows(rp, [entry])).to match_css_pattern( "tr td.name h1" => "Star" ) end it "should render argument-based html columns with custom data" do rp = test_report do scope { Entry } column(:name, :html => lambda {|data| content_tag :em, data}) do self.name.upcase end end expect(subject.datagrid_rows(rp, [entry])).to match_css_pattern( "tr td.name em" => "STAR" ) end it "should render html columns with double arguments for column" do rp = test_report do scope { Entry } column(:name, :html => true) do |model, grid| content_tag(:span, "#{model.name}-#{grid.assets.klass}" ) end end expect(subject.datagrid_rows(rp, [entry])).to match_css_pattern( "tr td.name span" => "Star-Entry" ) end it "should render argument-based html blocks with double arguments" do rp = test_report do scope { Entry } column(:name, :html => lambda { |data, model| content_tag :h1, "#{data}-#{model.name.downcase}" }) end expect(subject.datagrid_rows(rp, [entry])).to match_css_pattern( "tr td.name h1" => "Star-star" ) end it "should render argument-based html blocks with triple arguments" do rp = test_report do scope { Entry } column(:name, :html => lambda { |data, model, grid| content_tag :h1, "#{data}-#{model.name.downcase}-#{grid.assets.klass}" }) end expect(subject.datagrid_rows(rp, [entry])).to match_css_pattern( "tr td.name h1" => "Star-star-Entry" ) end it "should render argument-based html blocks with double arguments and custom data" do rp = test_report do scope { Entry } column(:name, :html => lambda { |data, model| content_tag :h1, "#{data}-#{model.name}" }) do self.name.upcase end end expect(subject.datagrid_rows(rp, [entry])).to match_css_pattern( "tr td.name h1" => "STAR-Star" ) end it "should render argument-based html blocks with triple arguments and custom data" do rp = test_report do scope { Entry } column(:name, :html => lambda { |data, model, grid| content_tag :h1, "#{data}-#{model.name}-#{grid.assets.klass}" }) do self.name.upcase end end expect(subject.datagrid_rows(rp, [entry])).to match_css_pattern( "tr td.name h1" => "STAR-Star-Entry" ) end it "should support columns option" do rp = test_report do scope { Entry } column(:name) column(:category) end expect(subject.datagrid_rows(rp, [entry], :columns => [:name])).to match_css_pattern( "tr td.name" => "Star" ) expect(subject.datagrid_rows(rp, [entry], :columns => [:name])).to match_css_pattern( "tr td.category" => 0 ) end it "should allow CSS classes to be specified for a column" do rp = test_report do scope { Entry } column(:name, :class => 'my_class') end expect(subject.datagrid_rows(rp, [entry])).to match_css_pattern( "tr td.name.my_class" => "Star" ) end context "when grid has complicated columns" do let(:grid) do test_report(:name => 'Hello') do scope {Entry} filter(:name) column(:name) do |model, grid| "'#{model.name}' filtered by '#{grid.name}'" end end end it "should ignore them" do expect(subject.datagrid_rows(grid, [entry])).to match_css_pattern( "td.name" => 1 ) end end it "should escape html" do entry.update_attributes!(:name => "