require File.dirname(__FILE__) + '/../../spec_helper'

def valid_<%=rule_name%>_rule_data
  '["Rule Title"]'
end
  
describe RulesEngine::Rule::<%=rule_class%> do

  def valid_attributes
    {
      :<%=rule_name%>_title => 'Rule Title'
    }
  end
  
  it "should be discoverable" do
    RulesEngine::Discovery.rule_class("RulesEngine::Rule::<%=rule_class%>").should == RulesEngine::Rule::<%=rule_class%>
  end

  describe "the expected class options" do    
    it "should be in the 'Twitter' group" do
      RulesEngine::Rule::<%=rule_class%>.options[:group].should == "Twitter"
    end
    
    it "should have the diplay name of 'Tweet Word Writer'" do
      RulesEngine::Rule::<%=rule_class%>.options[:display_name].should == "Tweet Word Writer"
    end

    it "should have the help template of '/re_rule_definitions/<%=rule_name%>/help'" do
      RulesEngine::Rule::<%=rule_class%>.options[:help_partial].should == '/re_rule_definitions/<%=rule_name%>/help'
    end

    it "should have the new template of '/re_rule_definitions/<%=rule_name%>/new'" do
      RulesEngine::Rule::<%=rule_class%>.options[:new_partial].should == '/re_rule_definitions/<%=rule_name%>/new'
    end

    it "should have the edit view partial template of '/re_rule_definitions/<%=rule_name%>/edit'" do
      RulesEngine::Rule::<%=rule_class%>.options[:edit_partial].should == '/re_rule_definitions/<%=rule_name%>/edit'
    end
  end
  
  describe "setting the rule data" do
    before(:each) do
      @<%=rule_name%> = RulesEngine::Rule::<%=rule_class%>.new
      @<%=rule_name%>.data = valid_<%=rule_name%>_rule_data
    end  
    
    describe "the data is valid" do
      it "should be valid" do
        @<%=rule_name%>.should be_valid
      end
            
      it "should set the title" do
        @<%=rule_name%>.title.should == "Rule Title"        
      end
    end

    describe "the data is nil" do
      it "should set the title to nil" do
        @<%=rule_name%>.title.should_not be_nil
        @<%=rule_name%>.data = nil
        @<%=rule_name%>.title.should be_nil
      end
    end
  end
  
  describe "the summary" do
    it "should not be blank" do
      <%=rule_name%> = RulesEngine::Rule::<%=rule_class%>.new
      <%=rule_name%>.summary.should_not be_blank
    end
  end

  describe "the data" do
    it "should be converted to a json string" do
      <%=rule_name%> = RulesEngine::Rule::<%=rule_class%>.new
      <%=rule_name%>.should_receive(:title).and_return("mock title")
      <%=rule_name%>.data.should == '["mock title"]'
    end
  end
  
  describe "the expected_outcomes" do
    it "should be outcome next" do
      <%=rule_name%> = RulesEngine::Rule::<%=rule_class%>.new
      <%=rule_name%>.expected_outcomes.should == [:outcome => RulesEngine::Rule::Outcome::NEXT]
    end
  end
  
  describe "setting the rule attributes" do
    before(:each) do
      @<%=rule_name%> = RulesEngine::Rule::<%=rule_class%>.new
    end  
    
    it "should be valid with valid attributes" do
      @<%=rule_name%>.attributes = valid_attributes
      @<%=rule_name%>.should be_valid
    end            
  
    describe "setting the <%=rule_name%>_title" do
      it "should set the title" do
        @<%=rule_name%>.attributes = valid_attributes
        @<%=rule_name%>.title.should == 'Rule Title'
      end            
    
      it "should not be valid if the '<%=rule_name%>_title' attribute is missing" do
        @<%=rule_name%>.attributes = valid_attributes.except(:<%=rule_name%>_title)
        @<%=rule_name%>.should_not be_valid
        @<%=rule_name%>.errors.should include(:<%=rule_name%>_title)
      end            
    
      it "should not be valid if the '<%=rule_name%>_title' attribute is blank" do
        @<%=rule_name%>.attributes = valid_attributes.merge(:<%=rule_name%>_title => "")
        @<%=rule_name%>.should_not be_valid
        @<%=rule_name%>.errors.should include(:<%=rule_name%>_title)
      end                
    end
  end
  
  describe "before a rule is created" do
    # xit "There is nothing to do here"
  end
  
  describe "before a rule is updated" do
    # xit "There is nothing to do here"
  end
  
  describe "before a rule is destroyed" do
    # xit "There is nothing to do here"
  end
  
  describe "processing the rule" do
    it "should return outcome 'NEXT'" do
      <%=rule_name%> = RulesEngine::Rule::<%=rule_class%>.new
      <%=rule_name%>.process(1001, {:tweet_words => []}).outcome.should == RulesEngine::Rule::Outcome::NEXT
    end
            
    describe "updateing the database" do
      it "should find_or_create tweet_word" do
        Re<%=rule_class%>List.should_receive(:find_or_create).with("one")
        Re<%=rule_class%>List.should_receive(:find_or_create).with("two")

        <%=rule_name%> = RulesEngine::Rule::<%=rule_class%>.new
        <%=rule_name%>.process(1001, {:tweet_words => ['one', 'two']})
      end        

      it "should update_time_codes for each tweet_word" do
        Re<%=rule_class%>Count.should_receive(:update_time_codes).with(1001)
        Re<%=rule_class%>Count.should_receive(:update_time_codes).with(2002)

        Re<%=rule_class%>List.stub!(:find_or_create).and_return(1001, 2002)
      
        <%=rule_name%> = RulesEngine::Rule::<%=rule_class%>.new
        <%=rule_name%>.process(1001, {:tweet_words => ['one', 'two']})
      end        
      
      it "should write to the database" do
        now = Time.parse('1 Jan 2000 12:00 pm')
        Time.stub!(:now).and_return(now)
        
        <%=rule_name%> = RulesEngine::Rule::<%=rule_class%>.new
        <%=rule_name%>.process(1001, {:tweet_words => ['one', 'two']})

        <%=rule_name%> = RulesEngine::Rule::<%=rule_class%>.new
        <%=rule_name%>.process(1002, {:tweet_words => ['one', 'three']})
          
        word_writer = Re<%=rule_class%>List.find(:all, :order => 'word')
        word_writer.map(&:word).should == ['one', 'three', 'two']
        
        time_codes = [now.strftime("%Y%m%d%H"), now.strftime("%Y%m%d"), now.strftime("%Y%m"), now.strftime("%Y")]
        word_count = Re<%=rule_class%>Count.find(:all, :order => "time_code DESC", :conditions => ["word_id = ?", word_writer[0].id])
        word_count.map(&:time_code).should == time_codes
        word_count.map(&:word_count).should == [2, 2, 2, 2]

        word_count = Re<%=rule_class%>Count.find(:all, :order => "time_code DESC", :conditions => ["word_id = ?", word_writer[1].id])
        word_count.map(&:time_code).should == time_codes
        word_count.map(&:word_count).should == [1, 1, 1, 1]

        word_count = Re<%=rule_class%>Count.find(:all, :order => "time_code DESC", :conditions => ["word_id = ?", word_writer[2].id])
        word_count.map(&:time_code).should == time_codes
        word_count.map(&:word_count).should == [1, 1, 1, 1]
        
        # add two hours
        now = now + 2.hours
        Time.stub!(:now).and_return(now)

        <%=rule_name%> = RulesEngine::Rule::<%=rule_class%>.new
        <%=rule_name%>.process(1002, {:tweet_words => ['one', 'three']})

        word_count = Re<%=rule_class%>Count.find(:all, :order => "time_code DESC", :conditions => ["word_id = ?", word_writer[0].id])
        word_count.map(&:time_code).should == [now.strftime("%Y%m%d%H")] + time_codes
        word_count.map(&:word_count).should == [1, 2, 3, 3, 3]        
      end
    end        
  end
end


describe ReWorkflowRulesController, :type => :controller  do
  integrate_views
  
  describe "RulesEngine::Rule::<%=rule_class%>" do
  
    before(:each) do
      controller.instance_eval { flash.stub!(:sweep) }

      RulesEngine::Discovery.discover!
        
      controller.stub!(:rules_engine_reader_access_required).and_return(true)
      controller.stub!(:rules_engine_editor_access_required).and_return(true)

      @re_workflow = ReWorkflow.make
      ReWorkflow.stub!(:find).and_return(@re_workflow)
    end  
  
    describe "help" do
      it "should assign the <%=rule_name%> rule class" do
        get :help, :rule_class_name => "RulesEngine::Rule::<%=rule_class%>"
        assigns[:rule_class].should == RulesEngine::Rule::<%=rule_class%>
      end
    end

    describe "new" do
      it "show the new form" do
        get :new, :rule_class_name => "RulesEngine::Rule::<%=rule_class%>"
        response.should have_tag("form#re_rule_new_form") do
          with_tag("input#<%=rule_name%>_title")
        end  
      end
    end
  
    describe "edit" do
      it "show the edit form" do
        re_rule = ReRule.make(:re_workflow_id => @re_workflow.id, 
                              :rule_class_name => "RulesEngine::Rule::<%=rule_class%>",
                              :data => valid_<%=rule_name%>_rule_data)
        ReRule.stub!(:find).and_return(re_rule)
      
        get :edit, :re_workflow_id => @re_workflow.id, :re_rule_id => 1001, :rule_class_name => "RulesEngine::Rule::<%=rule_class%>"
        response.should have_tag("form#re_rule_edit_form") do
          with_tag("input#<%=rule_name%>_title", :value => 'Rule Title')     
        end  
      end
    end
  end
end