Skip to content

Instantly share code, notes, and snippets.

@ashmoran
Created December 12, 2011 17:03
Show Gist options
  • Save ashmoran/1468200 to your computer and use it in GitHub Desktop.
Save ashmoran/1468200 to your computer and use it in GitHub Desktop.
An example of specifying two linked state_machines which disable and enable each other
describe Report::ReportStateMachine do
describe "state machine" do
describe "locking state machine" do
shared_examples_for "an unlocked report" do
it { should be_report_unlocked }
describe "updating the report" do
its(:can_update_content?) { should be_false }
its(:can_check_out_report?) { should be_true }
its(:can_check_in_report?) { should be_false }
end
describe "managing the locking system" do
its(:can_disable_locking_report?) { should be_true }
its(:can_enable_locking_report?) { should be_true } # idempotent operation
end
end
shared_examples_for "a locked report" do
it { should be_report_locked }
describe "updating the report" do
its(:can_update_content?) { should be_true }
its(:can_check_out_report?) { should be_false }
its(:can_check_in_report?) { should be_true }
end
describe "managing the locking system" do
its(:can_enable_locking_report?) { should be_false }
its(:can_disable_locking_report?) { should be_false }
end
end
shared_examples_for "a lockable report" do
it_behaves_like "an unlocked report"
describe "#check_out" do
before(:each) do
subject.check_out_report(user)
end
it_behaves_like "a locked report"
end
describe "#check_in" do
before(:each) do
subject.check_out_report(user)
subject.check_in_report
end
it_behaves_like "an unlocked report"
end
sanity_check { subject.state?(example.metadata[:workflow_state]).should be_true }
end
shared_examples_for "a non-lockable report" do
its(:can_check_out_report?) { should be_false }
its(:can_check_in_report?) { should be_false }
sanity_check { subject.state?(example.metadata[:workflow_state]).should be_true }
end
shared_examples_for "a report with a disabled workflow" do
[ :submit, :decline, :approve, :unapprove, :publish, :unpublish ].each do |event|
it "can't #{event}" do
subject.send(:"can_#{event}?").should be_false
end
specify {
expect { subject.send(event) }.to_not change { subject.state_name }
}
end
sanity_check { subject.state?(example.metadata[:workflow_state]).should be_true }
sanity_check { subject.should be_report_locked } # because this is the only thing that disables the workflow ATM
end
end
end
describe "lockability" do
subject { a_report_in_workflow_state(example.metadata[:workflow_state]) }
context workflow_state: "requested" do
it_behaves_like "a non-lockable report"
end
context workflow_state: "draft" do
it_behaves_like "a lockable report"
end
context workflow_state: "submitted" do
it_behaves_like "a lockable report"
end
context workflow_state: "approved" do
it_behaves_like "a non-lockable report"
end
context workflow_state: "published" do
it_behaves_like "a lockable report"
end
end
describe "locking the workflow" do
subject { a_report_in_workflow_state(example.metadata[:workflow_state]) }
before(:each) do
subject.check_out_report
end
context workflow_state: "draft" do
it_behaves_like "a report with a disabled workflow"
end
context workflow_state: "submitted" do
it_behaves_like "a report with a disabled workflow"
end
context workflow_state: "published" do
it_behaves_like "a report with a disabled workflow"
end
end
def a_report_in_workflow_state(state)
Report.make.tap { |report| report.advance_to(state) }
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment