require "spec_helper" describe "Manage Concurrency" do before(:each) do @document = Document.create! { |d| d.name = "John" } @document.reload end it "should assign the active_metadata_timestamp via mass assignment" do ts = Time.now params = {:name => "nuovo nome", :active_metadata_timestamp => ts} @document.update_attributes params @document.active_metadata_timestamp.should eq ts end it "should skip if no timestamp is provided" do @document.update_attributes :name => "nuovo nome" @document.conflicts.should be_nil end describe "am_timestamp" do it "should return nil if active_metadata_timestamp has not been provided" do @document.am_timestamp.should be_nil end it "should return a float if active_metadata_timestamp is instance of Time" do @document.active_metadata_timestamp = Time.now @document.am_timestamp.should be_an_instance_of Float end it "should return a float if active_metadata_timestamp is a String" do @document.active_metadata_timestamp = Time.now.to_f.to_s @document.am_timestamp.should be_an_instance_of Float end end describe "has_fatals_conflicts" do it "should return false if no fatals conflicts are present" do @document.has_fatals_conflicts?.should be_false end it "should return true if model has generated fatals conflicts" do @document.conflicts= {:fatals => [1]} @document.has_fatals_conflicts?.should be_true end end describe "when a field is modified and the form ts is subsequent of the history ts" do it "should save the new value and history must be updated with the latest change" do sleep 0.2.seconds params = {:name => "nuovo nome", :active_metadata_timestamp => Time.now} @document.update_attributes(params) @document.conflicts[:warnings].should be_empty @document.conflicts[:fatals].should be_empty hs = @document.history_for(:name) hs.count.should eq 2 hs.first.value.should eq "nuovo nome" Document.last.name.should eq "nuovo nome" end end describe "when a field is modified and the form ts is preceding the history ts" do it "should not change the model value and the history if the newest history value is equal to the submitted once" do form_timestamp = Time.now #someone change the field value sleep 0.2.seconds @document.update_attributes({:name => "nuovo nome", :active_metadata_timestamp => Time.now}) # user submit pushing the same value that was already saved by another user sleep 0.2.seconds @document.update_attributes({:name => "nuovo nome", :active_metadata_timestamp => form_timestamp}) @document.conflicts[:warnings].should be_empty @document.conflicts[:fatals].should be_empty hs = @document.history_for(:name) #last change shoudl not be recorded in history hs.count.should eq 2 hs.first.value.should eq "nuovo nome" Document.last.name.should eq "nuovo nome" end it "should register a warning if the history newest value is different from the submitted once but the submitting user has not modified the value" do #fixtures value = @document.name form_timestamp = Time.now params = {:name => "nuovo nome"} #someone change the field value sleep 0.2.seconds @document.update_attributes(params) # user submit a different value sleep 0.2.seconds different_params = {:name => value, :active_metadata_timestamp => form_timestamp} @document.update_attributes(different_params) #assetions warnings = @document.conflicts[:warnings] warnings.size.should eq 1 warnings[0][:name].value.should eq "nuovo nome" @document.conflicts[:fatals].should be_empty end it "when a warning is registered the submitted value is skipped" do #fixtures value = @document.name form_timestamp = Time.now params = {:name => "nuovo nome"} #someone change the field value sleep 0.2.seconds @document.update_attributes(params) # user submit a different value sleep 0.2.seconds different_params = {:name => value, :active_metadata_timestamp => form_timestamp} @document.update_attributes(different_params) #assetions hs = @document.history_for(:name) hs.count.should eq 2 hs.first.value.should eq "nuovo nome" Document.last.name.should eq "nuovo nome" end it "should reject the change as fatal if the history newest value is different from the submitted once and both user has changed the value" do #fixtures form_timestamp = Time.now params = {:name => "nuovo nome"} #someone change the field value sleep 0.2.seconds @document.update_attributes(params) # user submit a different value sleep 0.2.seconds different_params = {:name => "altro nome", :active_metadata_timestamp => form_timestamp} @document.update_attributes(different_params) #assetions fatals = @document.conflicts[:fatals] fatals.size.should eq 1 fatals[0][:name].value.should eq "nuovo nome" @document.conflicts[:warnings].should be_empty end it "when a fatal conflict occurs the submitted value is skipped" do #fixtures form_timestamp = Time.now params = {:name => "nuovo nome"} #someone change the field value sleep 0.2.seconds @document.update_attributes(params) # user submit a different value sleep 0.2.seconds different_params = {:name => "altro nome", :active_metadata_timestamp => form_timestamp} @document.update_attributes(different_params) #assetions hs = @document.history_for(:name) hs.count.should eq 2 hs.first.value.should eq "nuovo nome" Document.last.name.should eq "nuovo nome" end end end