require 'spec_helper' module Selections describe Selection do it("should be valid") { Factory(:selection).should be_valid } it("should require valid name") { Factory.build(:selection, :name => "").should_not be_valid } context "duplicates" do let(:parent_1) { Factory(:selection) } let(:parent_2) { Factory(:selection) } before { Factory(:selection, :name => "duplicate", :parent_id => parent_1.id) } it "should allow duplicates under different parents" do Factory.build(:selection, :name => "duplicate", :parent_id => parent_2.id).should be_valid end it "should not allow duplicates same parents" do Factory.build(:selection, :name => "duplicate", :parent_id => parent_1.id).should_not be_valid end end describe ".system_code" do context "autogenerating" do context "create" do context "parent" do it("should not generate system_code when one set") do Factory(:selection, :name => "Priorities", :system_code => "something_else").system_code.should == "something_else" end it("generate singular system_code") { Factory(:selection, :name => "Priorities").system_code.should == "priority" } it("generate system_code when name has spaces") { Factory(:selection, :name => "telephone prefixes").system_code.should == "telephone_prefix" } it("generate system_code when camelcased") { Factory(:selection, :name => "TelephonePrefixes").system_code.should == "telephone_prefix" } end context "children" do it "should contain auto parent and child code" do parent = Factory(:selection) child_1 = Factory(:selection, :parent => parent) child_1.system_code.should == "#{parent.name}_#{child_1.name}" end it "should be child system_code when defined" do parent = Factory(:selection, :system_code => "hello") child_1 = Factory(:selection, :parent => parent, :system_code => "world") child_1.system_code.should == "world" end it "should contain parent and child code when defined" do parent = Factory(:selection, :system_code => "hello") child_1 = Factory(:selection, :parent => parent, :name => "world") child_1.system_code.should == "hello_world" end end end context "update" do before { @parent = Factory(:selection) } it "should not autogenerate system_code" do @parent.update_attribute(:system_code, nil) @parent.update_attributes(:name => "hello") @parent.system_code.should be_nil end it "should not allow update of system_code" do @parent.system_code = "different" @parent.should have(1).error_on(:system_code) @parent.errors[:system_code].should include("cannot be changed") end end end context "uniqueness of system codes" do before { @selection_1 = Factory(:selection) } it("should not allow same system_codes") { FactoryGirl.build(:selection, :system_code => @selection_1.system_code).should_not be_valid } it("should allow same system_codes if one archived") do @selection_1.update_attributes(:archived => true) FactoryGirl.build(:selection, :system_code => @selection_1.system_code).should be_valid end end context "valid system_code characters" do it("should not allow !") { FactoryGirl.build(:selection, :system_code => "hello!world").should_not be_valid } it("should not allow $") { FactoryGirl.build(:selection, :system_code => "hello$world").should_not be_valid } it("should not allow starting with _") { FactoryGirl.build(:selection, :system_code => "_hello").should_not be_valid } it("should allow containing _") { FactoryGirl.build(:selection, :system_code => "hello_world").should be_valid } it "should not have spaces" do FactoryGirl.build(:selection, :system_code => "hello world").should_not be_valid end end end context "common data" do before do @parent_1 = Factory(:selection) @child_1 = Factory(:selection, :parent => @parent_1) @child_2 = Factory(:selection, :parent => @parent_1, :is_default => true) @child_3 = Factory(:selection, :parent => @parent_1) @child_4 = Factory(:selection, :parent => @parent_1) end describe ".to_s" do it "should return name when only relationship is defined" do company = Factory(:company, :state_id => @child_4.id) company.state.to_s.should == @child_4.name end end describe ".position" do it("should save positive position") { Factory(:selection, :position => 10).position.should == 10 } it("should save negative position") { Factory(:selection, :position => -20).position.should == -20 } it("should save 0 position") { Factory(:selection, :position => 0).position.should == 0 } it("should save string as 0 position") { Factory(:selection, :position => "hello").position.should == 0 } it("should return hidden_position as empty string") { Factory(:selection, :position => Selections::Selection::HIDDEN_POSITION).position.should be_nil } it("should save nil and return nil") { Factory(:selection, :position => nil).position.should be_nil } it("should save nil as hidden_position value") { Factory(:selection, :position => nil).position_value.should == Selections::Selection::HIDDEN_POSITION } end describe "default_order" do it "should return alpha order" do @child_3.update_attribute(:name, "abc") @parent_1.reload.children.should == [@child_3, @child_1, @child_2, @child_4] end it "should return alpha and numbers first if set" do @child_3.update_attributes!(:position => 10) @child_2.update_attributes!(:position => 20) @parent_1.reload.children.should == [@child_3, @child_2, @child_1, @child_4] end end describe ".filter_archived_except_selected" do it("should return all children") { @parent_1.children.filter_archived_except_selected(@child_3).should =~ @parent_1.children } context "one archived" do before { @child_3.update_attribute(:archived, true) } it("should return all children except archived") { @parent_1.children.filter_archived_except_selected(@child_1).should =~ @parent_1.children - [@child_3] } it("should return all children including archived if its selected") { @parent_1.children.filter_archived_except_selected(@child_3).should =~ @parent_1.children } it "should return all children including archived if its selected except other archived" do @child_1.update_attribute(:archived, true) @parent_1.children.filter_archived_except_selected(@child_3).should =~ @parent_1.children - [@child_1] end end end describe ".siblings_with_default_set" do it("should return item set to default") { @child_1.siblings_with_default_set.should == @child_2 } it("should not return itself") { @child_2.siblings_with_default_set.should be_nil } it "should return nothing if no default" do @child_2.update_attribute(:is_default, false) @child_1.siblings_with_default_set.should be_nil end end describe ".is_default" do context "setting default" do before { @child_1.update_attributes!(:is_default=>true) } it("should set default") { @child_1.is_default.should be_true } it("should remove default if any set within scope") do @child_1.update_attributes!(:is_default=>true) @child_2.reload.is_default.should be_false end end it "default should be set when adding new item with default on" do Factory(:selection, :parent => @parent_1, :is_default => true).is_default.should be_true end it "when adding new item with default set, should remove other default" do Factory(:selection, :parent => @parent_1, :is_default => true) @child_2.reload.is_default.should be_false end it "should not remove default item in another scope" do other_parent = Factory(:selection) Factory(:selection, :parent => other_parent) other_child_2 = Factory(:selection, :parent => other_parent, :is_default => true) @child_1.update_attributes!(:is_default => true) other_child_2.is_default.should be_true end it "should unset default and not set any other within scope" do @child_2.update_attributes!(:is_default => false) @parent_1.children.each do |child| child.is_default.should be_false end end end end describe ".archived" do it("should not be archived") { Factory(:selection).archived.should be_false } it("should be archived") { Factory(:selection, :archived => true).archived.should be_true } it "should not change archived_at" do original_time = Time.now - 2.days selection = Factory(:selection, :archived_at => original_time) selection.update_attributes(:archived => true) selection.archived_at.should == original_time end it "should unset default if archived" do default_selections @child_2.update_attributes(:archived => true) @child_2.reload.is_default.should be_false end end context "system_code finds" do describe "#method_missing" do before do @parent_1 = Factory(:selection, :system_code => "parent_1") @parent_2 = Factory(:selection, :system_code => "parent_2") @parent_3 = Factory(:selection, :system_code => "parent_3") end it("should return a item with system_code of parent_1") { Selection.parent_1.should == @parent_1 } it("should return a item with system_code of parent_2") { Selections::Selection.parent_2.should == @parent_2 } it("should cause an exception if does not exist") { lambda { Selections::Selection.parent_10 }.should raise_exception } it("should still do normal method missing finds") { Selections::Selection.find_by_system_code(@parent_1.system_code).should == @parent_1 } it("should still support inbuilt methods") { Selections::Selection.where(:system_code => @parent_1.system_code).first.should == @parent_1 } context "pluralized returns children" do before { @parent_1.children << [Factory(:selection), Factory(:selection)] } it("should return children") { Selections::Selection.parent_1s.should == @parent_1.children } it "'es' pluralization should return children" do @parent_1.update_attribute(:system_code, "status") Selections::Selection.statuses.should == @parent_1.children end end end end end end