require 'helper' class GroupedScope::SelfGrouppingTest < GroupedScope::TestCase describe 'General behavior' do before do @employee = FactoryGirl.create(:employee) end it 'return #ids array' do assert_equal [@employee.id], @employee.group.ids e1 = FactoryGirl.create :employee, :group_id => 3 e2 = FactoryGirl.create :employee, :group_id => 3 assert_same_elements [e1.id, e2.id], e1.group.ids end it 'return #quoted_ids string for use in sql statments' do assert_equal "#{@employee.id}", @employee.group.quoted_ids end it 'respond true to grouped associations' do assert @employee.group.respond_to?(:reports) end it 'raise a GroupedScope::NoGroupIdError exception for objects with no group_id schema' do FooBar.column_names.wont_include 'group_id' lambda{ GroupedScope::SelfGroupping.new(FooBar.new) }.must_raise(GroupedScope::NoGroupIdError) end it 'return correct predicate for GroupedScope::SelfGroupping object' do @employee.update_attribute :group_id, 82 expected_sql = /"group_id" IN \(SELECT "employees"\."id" FROM "employees" WHERE "employees"\."group_id" = 82/ assert_sql(expected_sql) { Employee.where(:group_id => @employee.group).all } assert_sql(expected_sql) { Employee.all(:conditions => {:group_id => @employee.group}) } assert_equal [@employee], Employee.where(:group_id => @employee.group).all end it 'allows you to ask if the group is present' do @employee.update_attribute :group_id, 28 assert_no_queries do assert @employee.group_id.present? assert @employee.group.present? end end it 'allows you to ask if the group is blank' do assert_no_queries do assert @employee.group_id.blank? assert @employee.group.blank? end end describe 'for #with_reflection' do before { @reflection = Employee.reflections[:reports] } it 'will set a reflection and always set it back to nil' do assert_nil @employee.group.reflection @employee.group.with_reflection(@reflection) do assert_equal @reflection, @employee.group.reflection end assert_nil @employee.group.reflection end it 'will use the primary key of the reflection' do pk = 'association_primary_key' @reflection.stubs :association_primary_key => pk @employee.group.with_reflection(@reflection) do assert_equal pk, @employee.group.send(:primary_key) end end end describe 'for Array delegates' do it 'respond to first/last' do [:first,:last].each do |method| assert @employee.group.respond_to?(method), "Should respond to #{method.inspect}" end end it 'respond to each' do assert @employee.group.respond_to?(:each) @employee.group.each do |employee| assert_instance_of Employee, employee end end end end describe 'Calling #group' do it 'returns a active record relation' do assert_instance_of ActiveRecord::Relation, FactoryGirl.create(:employee).group end describe 'with a NIL group_id' do before do @employee = FactoryGirl.create(:employee) end it 'return a collection of one' do assert_equal 1, @employee.group.size end it 'include self in group' do assert @employee.group.include?(@employee) end it 'returns a sql literal for #ids_sql scoped to single record' do @employee.group.ids_sql.must_be_instance_of Arel::Nodes::SqlLiteral @employee.group.ids_sql.must_match %r{SELECT \"employees\".\"id\" FROM \"employees\" WHERE \"employees\".\"id\" = #{@employee.id}} end end describe 'with a set group_id' do before do @employee = FactoryGirl.create(:employee, :group_id => 1) end it 'return a collection of one' do assert_equal 1, @employee.group.size end it 'include self in group' do assert @employee.group.include?(@employee) end it 'returns a sql literal for #ids_sql scoped to group' do new_group_id = 420 e1 = FactoryGirl.create :employee, :group_id => new_group_id e2 = FactoryGirl.create :employee, :group_id => new_group_id e1.group.ids_sql.must_be_instance_of Arel::Nodes::SqlLiteral e1.group.ids_sql.must_match %r{SELECT \"employees\".\"id\" FROM \"employees\" WHERE \"employees\".\"group_id\" = #{new_group_id}} end it 'allows the group to be further scoped' do new_group_id = 420 e1 = FactoryGirl.create :employee, :group_id => new_group_id, :name => 'Ken', :email => 'ken@actionmoniker.com' e2 = FactoryGirl.create :employee, :group_id => new_group_id, :name => 'Hostmaster', :email => 'hostmaster@actionmoniker.com' e3 = FactoryGirl.create :employee, :group_id => new_group_id, :name => 'Ken', :email => 'ken@metaskills.net' assert_same_elements [e1, e2], e1.group.email_for_actionmoniker end end describe 'with different groups available' do before do @e1 = FactoryGirl.create(:employee_with_reports, :group_id => 1) @e2 = FactoryGirl.create(:employee, :group_id => 1) @e3 = FactoryGirl.create(:employee_with_reports, :group_id => 2) @e4 = FactoryGirl.create(:employee, :group_id => 2) end it 'return a collection of group members' do assert_equal 2, @e1.group.size end it 'include all group members' do assert_same_elements [@e1,@e2], @e1.group end it 'allow member to find grouped associations of other member' do assert_same_elements @e1.reports, @e2.group.reports end it 'allow proxy owner to define all grouped which ignores group_id schema' do @e2.stubs :all_grouped? => true assert_same_elements [@e1,@e2,@e3,@e4], @e2.group assert_same_elements @e1.reports + @e3.reports, @e2.group.reports end end describe 'with different groups in legacy schema' do before do @e1 = FactoryGirl.create(:legacy_employee_with_reports, :group_id => 1) @e2 = FactoryGirl.create(:legacy_employee, :group_id => 1) @e3 = FactoryGirl.create(:legacy_employee_with_reports, :group_id => 2) @e4 = FactoryGirl.create(:legacy_employee, :group_id => 2) end it 'honor legacy reports association options like class_name and foreign_key' do @e2.group.reports.all? { |r| r.is_a?(LegacyReport) } end end end end