require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe "RulesEngine::Process::Runner" do describe "setting the runner" do it "should set the runner as a instance of a class" do mock_runner = mock('mock_runner') RulesEngine::Process.runner = mock_runner RulesEngine::Process.runner.should == mock_runner end it "should set the runner to the database plan runner" do RulesEngine::Process.runner = :db_runner RulesEngine::Process.runner.should be_instance_of(RulesEngine::Process::DbRunner) end end describe "getting the runner" do it "should throw an exception if the runner is not set" do RulesEngine::Process.runner = nil lambda { RulesEngine::Process.runner }.should raise_error end end describe "creating a process" do it "should throw an error if not overwritten" do lambda { RulesEngine::Process::Runner.new.create() }.should raise_error end end describe "getting the run status" do it "should throw an error if not overwritten" do lambda { RulesEngine::Process::Runner.new.status(10001) }.should raise_error end end describe "getting the run history" do it "should throw an error if not overwritten" do lambda { RulesEngine::Process::Runner.new.history(10001, {}) }.should raise_error end end describe "running plans and workflows" do before(:each) do @rule_class = mock("Rule Class") @rule_class.stub!(:new).and_return(@rule_class) @rule_class.stub!(:title).and_return('mock title') @rule_class.stub!(:data=) @rule_class.stub!(:process).and_return(RulesEngine::Rule::Outcome.new(RulesEngine::Rule::Outcome::NEXT)) RulesEngine::Discovery.stub!(:rule_class).and_return(@rule_class) RulesEngine::Process.auditor.stub!(:audit)# {|one, two, three| puts two } @runner = RulesEngine::Process::Runner.new @plan = {"code" => "plan_code", "version" => "1001", "workflow" => "one", "workflow_one" => { "rules" => [{ "rule_class_name" => "one_one", "data" => "one_one_data", },{ "rule_class_name" => "one_two", "data" => "one_two_data", },{ "rule_class_name" => "one_three", "data" => "one_two_data", }], "next_workflow" => "two" }, "workflow_two" => { "rules" => [{ "rule_class_name" => "two_one", "data" => "two_one_data", }], "next_workflow" => "three" }, "workflow_three" => { "rules" => [{ "rule_class_name" => "three_one", "data" => "three_one_data", }], "next_workflow" => "" } } end describe "running the plan" do it "should use the _run_plan_workflow method" do @runner.should_receive(:_run_plan_workflow) @runner.run_plan(10001, @plan, {}) end it "should be successfull with a valid plan" do @runner.run_plan(10001, @plan, {}).should == true end it "should fail with an invalid plan" do @runner.run_plan(10001, {}, {}).should == false end it "should audit the plan has started" do RulesEngine::Process.auditor.should_receive(:audit).once.with(10001, "Plan : plan_code : started", RulesEngine::Process::AUDIT_INFO) @runner.run_plan(10001, @plan, {}) end describe "run_workflow missing" do it "should audit the failure" do RulesEngine::Process.auditor.should_receive(:audit).once.with(10001, anything, RulesEngine::Process::AUDIT_FAILURE) @runner.run_plan(10001, @plan.except("workflow"), {}) end it "should return false" do @runner.run_plan(10001, @plan.except("workflow"), {}).should == false end end it "should process the workflow " do @runner.should_receive(:_run_workflow_rules).with(10001, @plan, @plan["workflow_one"], {:data => "mock data"}) @runner.run_plan(10001, @plan, {:data => "mock data"}) end describe "_run_workflow_rules outcomes" do describe "it returns no outcome" do it "should return success" do @runner.stub!(:_run_workflow_rules).and_return(nil) @runner.run_plan(10001, @plan, {}).should == true end end describe "it returns NEXT" do it "should return success" do @runner.stub!(:_run_workflow_rules).and_return(RulesEngine::Rule::Outcome.new(RulesEngine::Rule::Outcome::NEXT)) @runner.run_plan(10001, @plan, {}).should == true end end describe "it returns STOP SUCCESS" do it "should return success" do @runner.stub!(:_run_workflow_rules).and_return(RulesEngine::Rule::Outcome.new(RulesEngine::Rule::Outcome::STOP_SUCCESS)) @runner.run_plan(10001, @plan, {}).should == true end end describe "it returns STOP FAILURE" do it "should return failure" do @runner.stub!(:_run_workflow_rules).and_return(RulesEngine::Rule::Outcome.new(RulesEngine::Rule::Outcome::STOP_FAILURE)) @runner.run_plan(10001, @plan, {}).should == false end end describe "it returns START_WORKFLOW" do it "should return run the next workflow" do @runner.should_receive(:_run_workflow_rules).with(10001, @plan, @plan["workflow_one"], {:data => "mock data"}).and_return(RulesEngine::Rule::Outcome.new(RulesEngine::Rule::Outcome::START_WORKFLOW, 'two')) @runner.should_receive(:_run_workflow_rules).with(10001, @plan, @plan["workflow_two"], {:data => "mock data"}) @runner.run_plan(10001, @plan, {:data => "mock data"}).should == true end end it "should return false" do @runner.stub!(:_run_workflow_rules).and_return(RulesEngine::Rule::Outcome.new(RulesEngine::Rule::Outcome::START_WORKFLOW, 'one')) @runner.run_plan(10001, @plan, {}).should == false end end describe "running the workflow" do it "should load the rule" do RulesEngine::Discovery.should_receive(:rule_class).with("one_one").and_return(@rule_class) @rule_class.should_receive(:new).and_return(@rule_class) @rule_class.should_receive(:data=).with("one_one_data") @runner.run_plan(10001, @plan, {}).should == true end describe "the rules does not exist" do it "should return an error" do RulesEngine::Discovery.should_receive(:rule_class).with("one_one").and_return(nil) @runner.run_plan(10001, @plan, {}).should == false end end it "should proces the rule" do @rule_class.should_receive(:process) @runner.run_plan(10001, @plan, {}) end describe "processing a rule" do before(:each) do @test_rule = mock("Test Rule") @test_rule.stub!(:new).and_return(@test_rule) @test_rule.stub!(:title).and_return('mock title') @test_rule.stub!(:data=) RulesEngine::Discovery.stub!(:rule_class).with("one_one").and_return(@test_rule) end it "should pass the plan to the process" do @test_rule.should_receive(:process).with(10001, @plan, {:plan => "data"}) @runner.run_plan(10001, @plan, {:plan => "data"}) end describe "rule returns nil" do it "should proceed to the next rule" do @test_rule.stub!(:process).and_return(nil) RulesEngine::Discovery.should_receive(:rule_class).with("one_two") @runner.run_plan(10001, @plan, {}) end end describe "rule returns NEXT" do it "should proceed to the next rule" do @test_rule.stub!(:process).and_return(RulesEngine::Rule::Outcome.new(RulesEngine::Rule::Outcome::NEXT)) RulesEngine::Discovery.should_receive(:rule_class).with("one_two") @runner.run_plan(10001, @plan, {}) end end describe "rule returns STOP_SUCCESS" do it "should not proceed to the next rule" do @test_rule.stub!(:process).and_return(RulesEngine::Rule::Outcome.new(RulesEngine::Rule::Outcome::STOP_SUCCESS)) RulesEngine::Discovery.should_not_receive(:rule_class).with("one_two") @runner.run_plan(10001, @plan, {}) end it "should return success" do @test_rule.stub!(:process).and_return(RulesEngine::Rule::Outcome.new(RulesEngine::Rule::Outcome::STOP_SUCCESS)) @runner.run_plan(10001, @plan, {}) == true end end describe "rule returns STOP_FAILURE" do it "should not proceed to the next rule" do @test_rule.stub!(:process).and_return(RulesEngine::Rule::Outcome.new(RulesEngine::Rule::Outcome::STOP_FAILURE)) RulesEngine::Discovery.should_not_receive(:rule_class).with("one_two") @runner.run_plan(10001, @plan, {}) end it "should return failure" do @test_rule.stub!(:process).and_return(RulesEngine::Rule::Outcome.new(RulesEngine::Rule::Outcome::STOP_FAILURE)) @runner.run_plan(10001, @plan, {}) == false end end describe "rule returns START_WORKFLOW" do it "should not proceed to the next rule" do @test_rule.stub!(:process).and_return(RulesEngine::Rule::Outcome.new(RulesEngine::Rule::Outcome::START_WORKFLOW, 'three')) RulesEngine::Discovery.should_not_receive(:rule_class).with("one_two") @runner.run_plan(10001, @plan, {}) end it "should start the defined workflow" do @test_rule.stub!(:process).and_return(RulesEngine::Rule::Outcome.new(RulesEngine::Rule::Outcome::START_WORKFLOW, 'three')) RulesEngine::Discovery.should_not_receive(:rule_class).with("two_one") RulesEngine::Discovery.should_receive(:rule_class).with("three_one") @runner.run_plan(10001, @plan, {}) end end end end end describe "running the workflow" do it "should use the _run_plan_workflow method" do @runner.should_receive(:_run_plan_workflow) @runner.run_workflow(10001, @plan, "one", {}) end it "should be successfull with a valid plan" do @runner.run_workflow(10001, @plan, "one", {}).should == true end it "should fail with an invalid plan" do @runner.run_workflow(10001, {}, {}).should == false end end end end