require 'rails_helper'

RSpec.describe Dunlop::LastAttributeChangeHelper, type: :helper do
  subject { helper }
  describe '#last_changed_info' do
    let(:workflow_instance_1) { create :workflow_instance_scenario1 }
    let(:workflow_instance_2) { create :workflow_instance_scenario1 }
    let(:attr) { :initialization_check_done }
    let(:second_attr) { :my_identifier }
    context 'collection with activerecord relation' do
      let(:target){ ContractorInitialization::Scenario1::Collection.where(id: [workflow_instance_1.contractor_initialization.id, workflow_instance_2.contractor_initialization.id])}

      it "returns mixed for different changed values" do
        workflow_instance_1.contractor_initialization.last_attribute_changes.create changed_at: 1.minute.ago, attribute_name: attr
        workflow_instance_2.contractor_initialization.last_attribute_changes.create changed_at: 3.minutes.ago, attribute_name: attr
        expect( subject.last_changed_info target, attr ).to eq '(mixed)'
      end

      it "returns a timestamp when change timestamps are the same" do
        time = "2015-12-03T03:42:00Z".to_time
        workflow_instance_1.contractor_initialization.last_attribute_changes.create changed_at: time, attribute_name: attr
        workflow_instance_2.contractor_initialization.last_attribute_changes.create changed_at: time, attribute_name: attr
        expect( subject.last_changed_info target, attr ).to eq '3 dec 6:42' # test suite is Moscow
      end

      it "returns blank when no attribute changes are given" do
        expect( subject.last_changed_info target, attr ).to be_blank
      end

      it "reduces the number of queries on large collections with added relation refinement" do
        target.refine_relation{ with_last_attribute_changes }.map(&:state) # initiate subject first to remove the initialization queries. Only interested in the queries performed by helper method
        expect{
          subject.last_changed_info target, attr
          subject.last_changed_info target, second_attr
        }.not_to exceed_query_limit 1 # two records, two attributes should be done in one query
      end
    end

    context "collection array" do
      let(:target){ ContractorInitialization::Scenario1::Collection.new([workflow_instance_1.contractor_initialization, workflow_instance_2.contractor_initialization]) }

      it "returns mixed for different changed values" do
        workflow_instance_1.contractor_initialization.last_attribute_changes.create changed_at: 1.minute.ago, attribute_name: attr
        workflow_instance_2.contractor_initialization.last_attribute_changes.create changed_at: 3.minutes.ago, attribute_name: attr
        expect( subject.last_changed_info target, attr ).to eq '(mixed)'
      end

      it "returns a timestamp when change timestamps are the same" do
        time = "2015-12-03T03:42:00Z".to_time
        workflow_instance_1.contractor_initialization.last_attribute_changes.create changed_at: time, attribute_name: attr
        workflow_instance_2.contractor_initialization.last_attribute_changes.create changed_at: time, attribute_name: attr
        expect( subject.last_changed_info target, attr ).to eq '3 dec 6:42' # test suite is Moscow
      end

      it "returns blank when no attribute changes are given" do
        expect( subject.last_changed_info target, attr ).to be_blank
      end
    end

    context "activerecord model" do
      let(:target){ workflow_instance_1.contractor_initialization }
      it "returns a timestamp when there is one" do
        time = "2015-12-03T03:42:00Z".to_time
        workflow_instance_1.contractor_initialization.last_attribute_changes.create changed_at: time, attribute_name: attr
        expect( subject.last_changed_info target, attr ).to eq '3 dec 6:42' # test suite is Moscow
      end
    end
  end
end
