You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ode.apache.org by as...@apache.org on 2007/12/12 00:14:43 UTC
svn commit: r603406 [3/3] - in /ode/sandbox/singleshot: ./ app/controllers/
app/helpers/ app/models/ app/views/layouts/ app/views/sandwiches/
app/views/sessions/ app/views/tasks/ config/ config/environments/
config/initializers/ db/migrate/ doc/pages/ ...
Modified: ode/sandbox/singleshot/spec/controllers/tasks_controller_spec.rb
URL: http://svn.apache.org/viewvc/ode/sandbox/singleshot/spec/controllers/tasks_controller_spec.rb?rev=603406&r1=603405&r2=603406&view=diff
==============================================================================
--- ode/sandbox/singleshot/spec/controllers/tasks_controller_spec.rb (original)
+++ ode/sandbox/singleshot/spec/controllers/tasks_controller_spec.rb Tue Dec 11 15:14:39 2007
@@ -7,7 +7,7 @@
describe TasksController, 'authentication' do
- include Specs::Authentication, Specs::Tasks
+ include Specs::Tasks
before :all do
@person = person('assaf')
@@ -22,40 +22,40 @@
end
it 'should use session authentication for HTML requests' do
- post :create, :task=>default_values
+ post :create, :task=>default_task
response.should redirect_to(session_url)
end
it 'should accept session authentication' do
session_authenticate @person
Task.should_receive(:create!)
- post :create, :task=>default_values
+ post :create, :task=>default_task
end
it 'should use HTTP Basic authentication for XML requests' do
- post :create, :task=>default_values, :format=>'xml'
+ post :create, :task=>default_task, :format=>'xml'
response.should be_unauthorized
end
it 'should use HTTP Basic authentication for JSON requests' do
- post :create, :task=>default_values, :format=>'json'
+ post :create, :task=>default_task, :format=>'json'
response.should be_unauthorized
end
it 'should use HTTP Basic authentication if authentication header provider' do
http_authenticate 'assaf', 'wrong'
- post :create, :task=>default_values
+ post :create, :task=>default_task
response.should be_unauthorized
end
it 'should accept HTTP Basic authentication' do
http_authenticate 'assaf', 'secret'
Task.should_receive(:create!)
- post :create, :task=>default_values
+ post :create, :task=>default_task
end
it 'should redirect to login page with return to self' do
- post :create, :task=>default_values
+ post :create, :task=>default_task
response.should redirect_to(session_url)
flash[:return_to].should match(/^http:\/\/test.host\/tasks/)
end
@@ -65,7 +65,7 @@
describe TasksController, 'POST /tasks' do
- include Specs::Authentication, Specs::Tasks
+ include Specs::Tasks
before :each do
authenticate person('assaf')
@@ -75,33 +75,44 @@
route_for(:controller=>'tasks', :action=>'create').should eql('/tasks')
end
- it 'should err if not task specified' do
- post :create
- response.should be_bad_request
- response.should have_text(/missing task/i)
+ it 'should create empty task if no input provided' do
+ post :create, :format=>'json'
+ response.should be_see_other
+ task = Task.find(:first)
+ task.should be_reserved
+ response.headers['Location'].should eql(task_url(task))
+ end
+
+ it 'should create task from supplied inputs' do
+ post :create, :task=>default_task, :format=>'json'
+ response.should be_created
+ task = Task.find(:first)
+ task.should be_active
+ response.headers['Location'].should eql(task_url(task))
+ default_task.each { |key, val| task.send(key).should eql(val) }
end
it 'should infer XML as outcome MIME type from accepted content type' do
request.headers['CONTENT_TYPE'] = Mime::XML.to_s
- post :create, :task=>default_values
- Task.find(:first).outcome_type.should eql(Mime::XML)
+ post :create, :task=>default_task
+ Task.find(:first).outcome_type.should eql(Mime::XML.to_s)
end
it 'should infer JSON as outcome MIME type from accepted content type' do
request.headers['CONTENT_TYPE'] = Mime::JSON.to_s
- post :create, :task=>default_values
- Task.find(:first).outcome_type.should eql(Mime::JSON)
+ post :create, :task=>default_task
+ Task.find(:first).outcome_type.should eql(Mime::JSON.to_s)
end
it 'should default to XML as outcome MIME type for all other content types' do
- post :create, :task=>default_values
- Task.find(:first).outcome_type.should eql(Mime::XML)
+ post :create, :task=>default_task
+ Task.find(:first).outcome_type.should eql(Mime::XML.to_s)
end
it 'should ignore outcome MIME type in request' do
request.headers['CONTENT_TYPE'] = Mime::JSON.to_s
- post :create, :task=>default_values.merge(:outcome_type=>'application/xml')
- Task.find(:first).outcome_type.should eql(Mime::JSON)
+ post :create, :task=>default_task.merge(:outcome_type=>'application/xml')
+ Task.find(:first).outcome_type.should eql(Mime::JSON.to_s)
end
it 'should add authenticated user as task admin' do
@@ -110,7 +121,7 @@
admins.size.should eql(1)
admins.should include(person('assaf'))
end
- post :create, :task=>default_values
+ post :create, :task=>default_task
end
it 'should set authenticated user as task admin' do
@@ -119,19 +130,18 @@
admins.size.should eql(2)
admins.should include(person('assaf'), 'alex')
end
- post :create, :task=>default_values.merge(:admins=>['alex'])
+ post :create, :task=>default_task.merge(:admins=>['alex'])
end
end
describe TasksController, 'GET /tasks/{id}' do
- include Specs::Authentication, Specs::Tasks
+ include Specs::Tasks
before :each do
- authenticate person('admin')
- @task = Task.create(default_values.merge(:admins=>authenticated, :owner=>person('owner'),
- :creator=>person('creator'), :potential_owners=>person('potential')))
+ @task = Task.create(default_task.merge(@roles = all_roles))
+ authenticate person(@roles[:admins].first)
end
it 'should map to /tasks/{id}' do
@@ -143,6 +153,11 @@
lambda { get :show, :id=>0 }.should raise_error(ActiveRecord::RecordNotFound)
end
+ it 'should 404 if task not yet active' do
+ task = Task.reserve!(authenticated)
+ lambda { get :show, :id=>task.id }.should raise_error(ActiveRecord::RecordNotFound)
+ end
+
it 'should 404 if task already cancelled' do
@task.status = :cancelled ; @task.save!
lambda { get :show, :id=>@task.id }.should raise_error(ActiveRecord::RecordNotFound)
@@ -153,232 +168,710 @@
lambda { get :show, :id=>@task.id }.should raise_error(ActiveRecord::RecordNotFound)
end
- it 'should not be visible to excluded owners'
+ it 'should not be visible to admin' do
+ lambda { get :show, :id=>@task.id }.should_not raise_error
+ end
+
+ it 'should not be visible to owner' do
+ authenticate @roles[:owner]
+ lambda { get :show, :id=>@task.id }.should_not raise_error
+ end
+
+ it 'should not be visible to potential owner' do
+ authenticate @roles[:potential_owners].first
+ lambda { get :show, :id=>@task.id }.should_not raise_error
+ end
+
+ it 'should not be visible to excluded owners' do
+ authenticate @task.potential_owners[1]
+ @task.update_attributes! :excluded_owners=>[authenticated]
+ lambda { get :show, :id=>@task.id }.should raise_error(ActiveRecord::RecordNotFound)
+ end
end
-describe TasksController, 'PUT /tasks/{id}' do
- include Specs::Authentication, Specs::Tasks
- before :each do
- authenticate person('admin')
- @task = Task.create(default_values.merge(:admins=>authenticated, :owner=>person('owner'),
- :creator=>person('creator'), :potential_owners=>person('potential')))
+describe TasksController, 'PUT task', :shared=>true do
+ include Specs::Tasks
+
+ before :all do
+ @admin, @owner = people('admin', 'owner')
+ @observer, @excluded = people('observer', 'excluded')
+ @potential = people('potential', 'potential2')
end
+ before :each do
+ @task = Task.create!(default_task.merge(:admins=>@admin, :potential_owners=>@potential,
+ :excluded_owners=>@excluded, :observers=>@observer))
+ controller.use_rails_error_handling!
+ end
+
it 'should map to /tasks/{id}' do
- route_for(:controller=>'tasks', :action=>'update', :id=>1).should eql('/tasks/1')
+ route_for(:controller=>'tasks', :action=>'update', :id=>@task.id).should eql("/tasks/#{@task.id}")
lambda { route_for(:controller=>'tasks', :action=>'update') }.should raise_error(ActionController::RoutingError)
end
+end
+
+describe TasksController, 'PUT reserved task' do
+ include Specs::Tasks
+
+ before :each do
+ authenticate person('admin')
+ @task = Task.reserve!(authenticated)
+ controller.use_rails_error_handling!
+ end
+
it 'should 400 if no input provided' do
- put :update, :id=>0
+ put :update, :id=>@task.id
response.should be_bad_request
+ @task.reload.should be_reserved
end
- it 'should 404 if task not found' do
- lambda { put :update, :id=>0, :task=>{} }.should raise_error(ActiveRecord::RecordNotFound)
+ it 'should 404 if not associated with task' do
+ authenticate person('unknown')
+ put :update, :id=>@task.id, :task=>default_task
+ response.should be_not_found
+ @task.reload.should be_reserved
end
- it 'should 404 if task already cancelled' do
- @task.status = :cancelled ; @task.save!
- lambda { put :update, :id=>@task.id, :task=>{} }.should raise_error(ActiveRecord::RecordNotFound)
+ it 'should 200 and redirect back if task updated' do
+ put :update, :id=>@task.id, :task=>default_task
+ response.should redirect_to(task_url)
end
- it 'should 404 unless allowed to view task' do
- authenticate person('noone')
- lambda { put :update, :id=>@task.id, :task=>{} }.should raise_error(ActiveRecord::RecordNotFound)
+ it 'should update task' do
+ put :update, :id=>@task.id, :task=>default_task
+ @task.reload
+ default_task.each do |key, value|
+ @task.send(key).should eql(value)
+ end
+ end
+
+ it 'should change task status to active' do
+ put :update, :id=>@task.id, :task=>default_task
+ @task.reload.should be_active
+ end
+
+ it 'should retain task administrator if no admins specified' do
+ put :update, :id=>@task.id, :task=>default_task.except(:admins)
+ @task.reload.admins.should eql([authenticated])
+ end
+
+ it 'should retain authenticated admin when other admins specified' do
+ admins = people('foo', 'bar')
+ put :update, :id=>@task.id, :task=>default_task.merge(:admins=>admins)
+ @task.reload.admins.sort_by(&:id).should eql([authenticated] + admins)
end
+ it 'should 422 if task does not validate' do
+ put :update, :id=>@task.id, :task=>default_task.except(:title)
+ response.should be_unprocessable_entity
+ end
+
+ it 'should determine outcome type from content type if XML' do
+ request.headers['CONTENT_TYPE'] = 'application/xml'
+ put :update, :id=>@task.id, :task=>default_task
+ @task.reload.outcome_type.should eql('application/xml')
+ end
+
+ it 'should determine outcome type from content type if JSON' do
+ request.headers['CONTENT_TYPE'] = 'application/json'
+ put :update, :id=>@task.id, :task=>default_task
+ @task.reload.outcome_type.should eql('application/json')
+ end
+ it 'should allow changing of outcome type' do
+ put :update, :id=>@task.id, :task=>default_task.merge(:outcome_type=>'application/json')
+ @task.reload.outcome_type.should eql('application/json')
+ end
+
end
+describe TasksController, 'PUT active task' do
+ it_should_behave_like 'TasksController PUT task'
-describe TasksController, 'DELETE /tasks/{id}' do
- include Specs::Authentication, Specs::Tasks
+ it 'should 400 if no task input provided' do
+ authenticate @admin
+ put :update, :id=>@task.id
+ response.should be_bad_request
+ end
- before :each do
- authenticate person('admin')
- @task = Task.create(default_values.merge(:admins=>authenticated, :owner=>person('owner'),
- :creator=>person('creator'), :potential_owners=>person('potential')))
+ it 'should 404 if not associated with task' do
+ authenticate person('unknown')
+ put :update, :id=>@task.id, :task=>default_task
+ response.should be_not_found
end
- it 'should map to /tasks/{id}' do
- route_for(:controller=>'tasks', :action=>'destroy', :id=>1).should eql('/tasks/1')
- lambda { route_for(:controller=>'tasks', :action=>'destroy') }.should raise_error(ActionController::RoutingError)
+ it 'should allow administrator to change task' do
+ authenticate @admin
+ put :update, :id=>@task.id, :task=>{ :title=>'changed', :data=>{ 'foo'=>'bar' } }
+ @task.reload.title.should eql('changed')
+ @task.data.should == { 'foo'=>'bar' }
end
- it 'should 404 if task not found' do
- lambda { delete :destroy, :id=>0 }.should raise_error(ActiveRecord::RecordNotFound)
+ it 'should allow administrator to assign task' do
+ authenticate @admin
+ put :update, :id=>@task.id, :task=>{ :owner=>@potential.first }
+ @task.reload.owner.should eql(@potential.first)
end
- it 'should 404 if task already cancelled' do
- @task.status = :cancelled ; @task.save!
- lambda { delete :destroy, :id=>@task.id }.should raise_error(ActiveRecord::RecordNotFound)
+ it 'should not allow administrator to assign to excluded owner' do
+ authenticate @admin
+ put :update, :id=>@task.id, :task=>{ :owner=>@excluded }
+ response.should be_client_error
end
- it 'should 404 unless allowed to view task' do
- authenticate person('noone')
- lambda { delete :destroy, :id=>@task.id }.should raise_error(ActiveRecord::RecordNotFound)
+ it 'should allow potential owner to claim task' do
+ authenticate @potential.first
+ put :update, :id=>@task.id, :task=>{ :owner=>@potential.first }
+ @task.reload.owner.should eql(@potential.first)
+ end
+
+ it 'should 404 if excluded owner attempts to claim task' do
+ authenticate @excluded
+ put :update, :id=>@task.id, :task=>{ :owner=>@excluded }
+ response.should be_not_found
+ end
+
+ it 'should not allow anyone but administrator to assign task' do
+ authenticate @potential.first
+ put :update, :id=>@task.id, :task=>{ :owner=>@observer }
+ @task.reload.owner.should be_nil
+ end
+
+ it 'should 200 and redirect back after update' do
+ authenticate @admin
+ put :update, :id=>@task.id, :task=>{}
+ response.should redirect_to(task_url)
end
- it 'should 403 if task already completed' do
- @task.status = :completed ; @task.save!
- delete :destroy, :id=>@task.id, :format=>'xml'
+ it 'should keep task status as active' do
+ authenticate @admin
+ put :update, :id=>@task.id, :task=>{}
+ @task.reload.should be_active
+ end
+
+ it 'should allow adminstrator to change status to suspended' do
+ authenticate @admin
+ put :update, :id=>@task.id, :task=>{ :status=>'suspended' }
+ @task.reload.should be_suspended
+ end
+
+ it 'should 403 if anyone else attempts to change task' do
+ authenticate @observer
+ put :update, :id=>@task.id, :task=>{}
+ response.should be_forbidden
+ end
+
+ it 'should allow changing of outcome type' do
+ authenticate @admin
+ put :update, :id=>@task.id, :task=>{ :outcome_type=>'application/json' }
+ @task.reload.outcome_type.should eql('application/json')
+ end
+
+ it 'should not change outcome type unless specified' do
+ request.headers['CONTENT_TYPE'] = 'application/json'
+ @task.update_attributes! :outcome_type=>'application/json'
+ authenticate @admin
+ put :update, :id=>@task.id, :task=>{}
+ @task.reload.outcome_type.should eql('application/json')
+ end
+
+end
+
+describe TasksController, 'PUT claimed task' do
+ it_should_behave_like 'TasksController PUT task'
+
+ before(:each) { @task.owner = @owner ; @task.save! }
+
+ it 'should allow owner to release task if other potential owners' do
+ authenticate @owner
+ put :update, :id=>@task.id, :task=>{ :owner=>nil }
+ @task.reload.owner.should be_nil
+ end
+
+ it 'should allow owner to delegate task' do
+ authenticate @owner
+ put :update, :id=>@task.id, :task=>{ :owner=>@observer }
+ @task.reload.owner.should eql(@observer)
+ end
+
+ it 'should not allow assigning to excluded owner' do
+ authenticate @owner
+ put :update, :id=>@task.id, :task=>{ :owner=>@excluded }
+ response.should be_client_error
+ response.should have_text(/excluded owner/i)
+ end
+
+ it 'should allow owner to change task data' do
+ authenticate @owner
+ put :update, :id=>@task.id, :task=>{ :title=>'changed', :data=>{ 'foo'=>'bar' } }
+ @task.reload.title.should eql(default_task[:title])
+ @task.data.should == { 'foo'=>'bar' }
+ end
+
+ it 'should allow administrator to change task state' do
+ authenticate @admin
+ put :update, :id=>@task.id, :task=>{ :title=>'changed', :data=>{ 'foo'=>'bar' } }
+ @task.reload.title.should eql('changed')
+ @task.data.should == { 'foo'=>'bar' }
+ end
+
+ it 'should 403 if potential owner attempts to change task' do
+ authenticate @potential.first
+ put :update, :id=>@task.id, :task=>{ }
+ response.should be_forbidden
+ end
+
+ it 'should 403 if potential owner claims task' do
+ authenticate @potential.first
+ put :update, :id=>@task.id, :task=>{ :owner=>@potential.first }
+ response.should be_forbidden
+ end
+
+ it 'should 403 if owner releases task and no potential owners' do
+ @task.update_attributes! :potential_owners=>@owner
+ authenticate @owner
+ put :update, :id=>@task.id, :task=>{ :owner=>nil }
+ response.should be_forbidden
+ end
+
+end
+
+
+describe TasksController, 'PUT suspended task' do
+ it_should_behave_like 'TasksController PUT task'
+
+ before(:each) { @task.owner = @owner ; @task.status = :suspended ; @task.save! }
+
+ it 'should allow admin to change task' do
+ authenticate @admin
+ put :update, :id=>@task.id, :task=>{ :title=>'changed', :data=>{ 'foo'=>'bar' } }
+ @task.reload.title.should eql('changed')
+ @task.data.should == { 'foo'=>'bar' }
+ end
+
+ it 'should keep task suspended' do
+ authenticate @admin
+ put :update, :id=>@task.id, :task=>{}
+ @task.reload.should be_suspended
+ end
+
+ it 'should allow admin to change status to active' do
+ authenticate @admin
+ put :update, :id=>@task.id, :task=>{ :status=>'active' }
+ @task.reload.should be_active
+ end
+
+ it 'should 403 if anyone else changes status to active' do
+ authenticate @owner
+ put :update, :id=>@task.id, :task=>{ :status=>'active' }
+ response.should be_forbidden
+ end
+
+ it 'should 403 if owner attempts to change task' do
+ authenticate @owner
+ put :update, :id=>@task.id, :task=>{}
response.should be_forbidden
end
- it 'should cancel task if administrator' do
+ it 'should 403 if potential owner attempts to change task' do
+ authenticate @potential.first
+ put :update, :id=>@task.id, :task=>{ :owner=>@potential.first }
+ response.should be_forbidden
+ end
+
+end
+
+describe TasksController, 'PUT completed task' do
+ it_should_behave_like 'TasksController PUT task'
+
+ before(:each) { @task.status = :completed ; @task.owner = @owner ; @task.save! }
+
+ it 'should 404 if not associated with task' do
+ authenticate person('unknown')
+ put :update, :id=>@task.id, :task=>default_task
+ response.should be_not_found
+ @task.reload.should be_completed
+ end
+
+ it 'should 409 if associated with task' do
+ authenticate @admin
+ put :update, :id=>@task.id, :task=>default_task
+ response.should be_conflict
+ @task.reload.should be_completed
+ end
+
+ it 'should not change task' do
+ authenticate @admin
+ put :update, :id=>@task.id, :task=>default_task.merge(:title=>'changed')
+ @task.reload.title.should_not eql('changed')
+ end
+
+end
+
+describe TasksController, 'PUT cancelled task' do
+ it_should_behave_like 'TasksController PUT task'
+
+ before(:each) { @task.status = :cancelled ; @task.save! }
+
+ it 'should 404 if not associated with task' do
+ authenticate person('unknown')
+ put :update, :id=>@task.id, :task=>default_task
+ response.should be_not_found
+ @task.reload.should be_cancelled
+ end
+
+ it 'should 404 if associated with task' do
+ authenticate @admin
+ put :update, :id=>@task.id, :task=>default_task
+ response.should be_not_found
+ @task.reload.should be_cancelled
+ end
+
+end
+
+
+describe TasksController, 'DELETE task', :shared=>true do
+ include Specs::Tasks
+
+ before :each do
+ @admin, @owner = people('admin', 'owner')
+ @task = Task.create!(default_task.merge(:admins=>@admin, :owner=>@owner))
+ controller.use_rails_error_handling!
+ end
+
+ it 'should map to /tasks/{id}' do
+ route_for(:controller=>'tasks', :action=>'destroy', :id=>@task.id).should eql("/tasks/#{@task.id}")
+ lambda { route_for(:controller=>'tasks', :action=>'destroy') }.should raise_error(ActionController::RoutingError)
+ end
+
+end
+
+describe TasksController, 'DELETE reserved task' do
+ include Specs::Tasks
+
+ before :each do
+ @admin = person('admin')
+ @task = Task.reserve!(@admin)
+ controller.use_rails_error_handling!
+ end
+
+ it 'should 404 if not associated with task' do
+ authenticate person('unknown')
delete :destroy, :id=>@task.id
- Task.find(@task.id).status.should eql(:cancelled)
+ response.should be_not_found
+ Task.should have(1).record
end
- it 'should cancel task if owner and owner allowed to cancel' do
- authenticate person('owner')
- @task.cancellation = :owner ; @task.save!
+ it 'should 200 if task deleted' do
+ authenticate @admin
delete :destroy, :id=>@task.id
- Task.find(@task.id).status.should eql(:cancelled)
+ response.should be_ok
+ response.body.should be_blank
end
- it 'should 403 if owner and owner not allowed to cancel' do
- authenticate person('owner')
+ it 'should delete task' do
+ authenticate @admin
delete :destroy, :id=>@task.id
- Task.find(@task.id).status.should eql(:active)
+ Task.should have(:no).records
end
- it 'should 403 if potential owner and not anyone allowed to cancel' do
- authenticate person('potential')
+end
+
+describe TasksController, 'DELETE active task' do
+ it_should_behave_like 'TasksController DELETE task'
+
+ it 'should 404 if not associated with task' do
+ authenticate person('unknown')
delete :destroy, :id=>@task.id
- Task.find(@task.id).status.should eql(:active)
+ response.should be_not_found
+ @task.reload.should be_active
end
- it 'should redirect to tasks list if cancelled and responding with HTML' do
+ it 'should 403 if not task administrator' do
+ authenticate @owner
delete :destroy, :id=>@task.id
- response.should redirect_to(tasks_url)
+ response.should be_forbidden
+ @task.reload.should be_active
end
- it 'should return 200 if cancelled and responding with XML' do
- delete :destroy, :id=>@task.id, :format=>'xml'
+ it 'should 200 if task cancelled' do
+ authenticate @admin
+ delete :destroy, :id=>@task.id
response.should be_ok
+ response.body.should be_blank
+ end
+
+ it 'should change task status to cancelled' do
+ authenticate @admin
+ delete :destroy, :id=>@task.id
+ @task.reload.should be_cancelled
+ end
+
+ it 'should not cancel if owner and cancellation policy is admin' do
+ authenticate @owner
+ delete :destroy, :id=>@task.id
+ @task.reload.should be_active
end
- it 'should return 200 if cancelled and responding with JSON' do
- delete :destroy, :id=>@task.id, :format=>'json'
+ it 'should cancel if owner and cancellation policy is owner' do
+ @task.update_attributes! :cancellation=>:owner
+ authenticate @owner
+ delete :destroy, :id=>@task.id
+ @task.reload.should be_cancelled
+ end
+
+end
+
+describe TasksController, 'DELETE suspended task' do
+ it_should_behave_like 'TasksController DELETE task'
+
+ before(:each) { @task.status = :suspended ; @task.save! }
+
+ it 'should 200 if task cancelled' do
+ authenticate @admin
+ delete :destroy, :id=>@task.id
response.should be_ok
+ response.body.should be_blank
end
- it 'should redirect back and flash error if cancelled and responding with HTML' do
- authenticate person('potential')
- request.env['HTTP_REFERER'] = '/source/page'
+ it 'should change task status to cancelled' do
+ authenticate @admin
delete :destroy, :id=>@task.id
- flash[:error].should match(/not allowed to cancel/i)
- response.should redirect_to('/source/page')
+ @task.reload.should be_cancelled
end
- it 'should return 403 if cancelled and responding with XML' do
- authenticate person('potential')
- delete :destroy, :id=>@task.id, :format=>'xml'
- response.should be_forbidden
+end
+
+describe TasksController, 'DELETE completed task' do
+ it_should_behave_like 'TasksController DELETE task'
+
+ before(:each) { @task.status = :completed ; @task.save! }
+
+ it 'should 404 if not associated with task' do
+ authenticate person('unknown')
+ delete :destroy, :id=>@task.id
+ response.should be_not_found
+ @task.reload.should be_completed
end
- it 'should return 403 if cancelled and responding with JSON' do
- authenticate person('potential')
- delete :destroy, :id=>@task.id, :format=>'json'
- response.should be_forbidden
+ it 'should 409 if associated with task' do
+ authenticate @admin
+ delete :destroy, :id=>@task.id
+ response.should be_conflict
+ @task.reload.should be_completed
end
end
+describe TasksController, 'DELETE cancelled task' do
+ it_should_behave_like 'TasksController DELETE task'
-describe TasksController, 'POST /tasks/{id}' do
- include Specs::Authentication, Specs::Tasks
+ before(:each) { @task.status = :cancelled ; @task.save! }
- before :each do
- authenticate person('owner')
- @task = Task.create(default_values.merge(:admins=>person('admin'), :owner=>authenticated,
- :creator=>person('creator'), :potential_owners=>person('potential')))
+ it 'should 404 if not associated with task' do
+ authenticate person('unknown')
+ delete :destroy, :id=>@task.id
+ response.should be_not_found
+ Task.should have(1).record
end
+ it 'should 404 if associated with task' do
+ authenticate @admin
+ delete :destroy, :id=>@task.id
+ response.should be_not_found
+ Task.should have(1).record
+ end
+
+end
+
+
+describe TasksController, 'POST task', :shared=>true do
+ include Specs::Tasks
+
+ before :each do
+ @admin, @owner = people('admin', 'owner')
+ @task = Task.create!(default_task.merge(:admins=>@admin, :owner=>@owner))
+ controller.use_rails_error_handling!
+ end
+
it 'should map to /tasks/{id}' do
- route_for(:controller=>'tasks', :action=>'complete', :id=>1).should eql('/tasks/1')
+ route_for(:controller=>'tasks', :action=>'complete', :id=>@task.id).should eql("/tasks/#{@task.id}")
lambda { route_for(:controller=>'tasks', :action=>'complete') }.should raise_error(ActionController::RoutingError)
end
- it 'should 400 if no input provided' do
- post :complete, :id=>0
- response.should be_bad_request
+ it 'should map to /tasks/{id}.{format}' do
+ route_for(:controller=>'tasks', :action=>'complete', :id=>@task.id, :format=>'xml').should eql("/tasks/#{@task.id}.xml")
end
- it 'should 404 if task not found' do
- lambda { post :complete, :id=>0, :task=>{} }.should raise_error(ActiveRecord::RecordNotFound)
- end
+end
- it 'should 404 if task already cancelled' do
- @task.status = :cancelled ; @task.save!
- lambda { post :complete, :id=>@task.id, :task=>{} }.should raise_error(ActiveRecord::RecordNotFound)
+describe TasksController, 'POST reserved task' do
+ include Specs::Tasks
+
+ before :each do
+ @admin = person('admin')
+ @task = Task.reserve!(@admin)
+ controller.use_rails_error_handling!
end
- it 'should 404 unless allowed to view task' do
- authenticate person('noone')
- lambda { post :complete, :id=>@task.id, :task=>{} }.should raise_error(ActiveRecord::RecordNotFound)
+ it 'should 404' do
+ authenticate @admin
+ post :complete, :id=>@task.id
+ response.should be_not_found
+ Task.should have(1).record
end
- it 'should redirect back and flash error if task already completed and requesting HTML' do
- @task.status = :completed ; @task.save!
- request.env['HTTP_REFERER'] = '/source/page'
- post :complete, :id=>@task.id, :task=>{}
- flash[:error].should match(/not allowed to complete/i)
- response.should redirect_to('/source/page')
+end
+
+describe TasksController, 'POST active task' do
+ it_should_behave_like 'TasksController POST task'
+
+ before(:each) { authenticate @owner }
+
+ it 'should 404 if not associated with task' do
+ authenticate person('unknown')
+ post :complete, :id=>@task.id
+ response.should be_not_found
+ @task.reload.should be_active
end
- it 'should 403 if task already completed and requesting XML' do
- @task.status = :completed ; @task.save!
- post :complete, :id=>@task.id, :task=>{}, :format=>'xml'
+ it 'should 403 if not task owner' do
+ authenticate @admin
+ post :complete, :id=>@task.id
response.should be_forbidden
+ @task.reload.should be_active
+ end
+
+ it 'should 200 if task completed' do
+ post :complete, :id=>@task.id
+ response.should be_ok
end
- it 'should 403 if task already completed and requesting JSON' do
- @task.status = :completed ; @task.save!
- post :complete, :id=>@task.id, :task=>{}, :format=>'json'
+ it 'should change task status to completed' do
+ post :complete, :id=>@task.id
+ @task.reload.should be_completed
+ end
+
+ it 'should leave task data intact if no data provided' do
+ data = { 'foo'=>'cow', 'bar'=>'bell' }
+ @task.update_attributes! :data=>data
+ post :complete, :id=>@task.id
+ @task.reload.data.should == data
+ end
+
+ it 'should change task data if new data provided' do
+ @task.update_attributes! :data=>{ 'foo'=>'cow', 'bar'=>'bell' }
+ data = { 'foo'=>'more' }
+ post :complete, :id=>@task.id, :task=>{ :data=>data }
+ @task.reload.data.should == data
+ end
+
+end
+
+describe TasksController, 'POST suspended task' do
+ it_should_behave_like 'TasksController POST task'
+
+ before(:each) { @task.status = :suspended ; @task.save! }
+
+ it 'should 403' do
+ authenticate @owner
+ post :complete, :id=>@task.id
response.should be_forbidden
end
- it 'should complete task if owner' do
- post :complete, :id=>@task.id, :task=>{}
- Task.find(@task.id).status.should eql(:completed)
+end
+
+describe TasksController, 'POST completed task' do
+ it_should_behave_like 'TasksController POST task'
+
+ before(:each) { @task.status = :completed ; @task.save! }
+
+ it 'should 409' do
+ authenticate @owner
+ post :complete, :id=>@task.id
+ response.should be_conflict
end
- it 'should 403 if not owner' do
- authenticate person('admin')
- post :complete, :id=>@task.id, :task=>{}, :format=>'xml'
+end
+
+describe TasksController, 'POST unclaimed task' do
+ it_should_behave_like 'TasksController POST task'
+
+ before(:each) { @task.owner = nil ; @task.save! }
+
+ it 'should 403' do
+ authenticate @admin
+ post :complete, :id=>@task.id
response.should be_forbidden
end
- it 'should 200 and redirect back to tasks list if completed and requesting HTML' do
- post :complete, :id=>@task.id, :task=>{}
- response.should redirect_to(tasks_url)
+end
+
+describe TasksController, 'POST cancelled task' do
+ it_should_behave_like 'TasksController POST task'
+
+ before(:each) { @task.status = :cancelled ; @task.save! }
+
+ it 'should 404' do
+ authenticate @owner
+ post :complete, :id=>@task.id
+ response.should be_not_found
+ @task.reload.should be_cancelled
+ end
+
+end
+
+
+
+describe TasksController, 'token authentication' do
+ include Specs::Tasks
+
+ before :each do
+ @task = Task.create(default_task.merge(:owner=>person('owner'), :potential_owners=>person('excluded'),
+ :excluded_owners=>person('excluded')))
end
- it 'should 200 if completed and requesting XML' do
- post :complete, :id=>@task.id, :task=>{}, :format=>'xml'
+ def authenticate(person)
+ credentials = ['_token', @task.token_for(person)]
+ request.headers['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials(*credentials)
+ end
+
+ it 'should be used if provided' do
+ authenticate person('owner')
+ get :show, :id=>@task.id
response.should be_ok
end
- it 'should 200 if completed and requesting JSON' do
- post :complete, :id=>@task.id, :task=>{}, :format=>'json'
+ it 'should authenticate stakeholder' do
+ authenticate person('owner')
+ get :show, :id=>@task.id
response.should be_ok
+ assigns[:authenticated] == person('owner')
end
- it 'should update task data if supplied' do
- post :complete, :id=>@task.id, :task=>{ :data=>{ :foo=>:bar } }
- Task.find(@task.id).data.should == {'foo'=>'bar'}
+ it 'should 404 if not stakeholder' do
+ authenticate person('noone')
+ lambda { get :show, :id=>@task.id }.should raise_error(ActiveRecord::RecordNotFound)
end
- it 'should leave task data intact if absent' do
- @task.data = { 'bar'=>'baz' } ; @task.save!
- post :complete, :id=>@task.id, :task=>{}
- Task.find(@task.id).data.should == {'bar'=>'baz'}
+ it 'should 404 if excluded owner' do
+ authenticate person('excluded')
+ lambda { get :show, :id=>@task.id }.should raise_error(ActiveRecord::RecordNotFound)
end
+ it 'should 404 if no such task' do
+ authenticate person('owner')
+ lambda { get :show, :id=>@task.id + 1 }.should raise_error(ActiveRecord::RecordNotFound)
+ end
+
+ it 'should 404 if task cancelled' do
+ @task.status = :cancelled ; @task.save!
+ authenticate person('owner')
+ lambda { get :show, :id=>@task.id }.should raise_error(ActiveRecord::RecordNotFound)
+ end
+
end
Modified: ode/sandbox/singleshot/spec/models/task_spec.rb
URL: http://svn.apache.org/viewvc/ode/sandbox/singleshot/spec/models/task_spec.rb?rev=603406&r1=603405&r2=603406&view=diff
==============================================================================
--- ode/sandbox/singleshot/spec/models/task_spec.rb (original)
+++ ode/sandbox/singleshot/spec/models/task_spec.rb Tue Dec 11 15:14:39 2007
@@ -1,43 +1,75 @@
require File.dirname(__FILE__) + '/../spec_helper'
-describe Task, 'to_param' do
+describe Task, 'reserve!' do
include Specs::Tasks
- before :each do
- @task = Task.create!
+ before :all do
+ @admin = person('admin')
+ @task = Task.reserve!(@admin)
+ end
+
+ it 'should create new task' do
+ Task.should have(1).record
+ end
+
+ it 'should be reserved' do
+ @task.should be_reserved
end
- def title
- @task.to_param[/(\d+-)(.*)/, 2]
+ it 'should include argument as admin' do
+ @task.admins.should eql([@admin])
+ end
+
+ it 'should destroy stakeholder when deleted' do
+ lambda { @task.destroy }.should change(Stakeholder, :count).to(0)
+ end
+
+end
+
+
+describe Task, 'to_param' do
+ include Specs::Tasks
+
+ it 'should return nil unless task saved' do
+ Task.new.to_param.should be_nil
end
it 'should resolve to task ID' do
- @task.to_param.to_i.should eql(@task.id)
+ task = Task.create!(default_task)
+ task.to_param.to_i.should eql(task.id)
+ task.update_attributes! :title=>'whatever'
+ task.to_param.to_i.should eql(task.id)
end
- it 'should contain title' do
- title.should eql(@task.title.gsub(' ', '-'))
+ it 'should only contain ID if title is empty' do
+ task = Task.reserve!(person('admin'))
+ task.to_param.should eql(task.id.to_s)
+ end
+
+ it 'should contain title if specified' do
+ task = Task.create(default_task.merge(:title=>'whatever'))
+ task.to_param.should eql("#{task.id}-whatever")
end
it 'should change all non-word characters to dashes' do
- @task.title = 'foo*bar+baz faz_'
- title.should eql('foo-bar-baz-faz_')
+ task = Task.create(default_task.merge(:title=>'foo*bar+baz faz_'))
+ task.to_param[/^\d+-(.*)/, 1].should eql('foo-bar-baz-faz_')
end
it 'should consolidate multiple dashes' do
- @task.title = 'foo**bar--baz -faz'
- title.should eql('foo-bar-baz-faz')
+ task = Task.create(default_task.merge(:title=>'foo**bar--baz -faz'))
+ task.to_param[/^\d+-(.*)/, 1].should eql('foo-bar-baz-faz')
end
it 'should remove dashes at end' do
- @task.title = 'foo**'
- title.should eql('foo')
+ task = Task.create(default_task.merge(:title=>'foo**'))
+ task.to_param[/^\d+-(.*)/, 1].should eql('foo')
end
it 'should leave UTF-8 text along' do
- @task.title = 'josé'
- CGI.escape(title).should eql('jos%C3%A9')
+ task = Task.create(default_task.merge(:title=>'josé'))
+ CGI.escape(task.to_param[/^\d+-(.*)/, 1]).should eql('jos%C3%A9')
end
end
@@ -47,34 +79,49 @@
include Specs::Tasks
before :each do
- @task = Task.new
+ @task = Task.create!(default_task)
end
it 'should default to :active' do
@task.status.should eql(:active)
end
- it 'should allow valid status code' do
- Task::STATUSES.each do |status|
- @task.status = status
- @task.save
- Task.find(@task.id).status.should eql(status)
- end
+ it 'should be required to save' do
+ @task.status = nil
+ @task.should have(1).error_on(:status)
end
- it 'should reject unknown status code' do
- @task.status = :unknown
- lambda { @task.save! }.should raise_error(ActiveRecord::RecordInvalid)
+ it 'should not change to completed without owner' do
+ @task.status = :completed
+ @task.should have(1).error_on(:status)
end
- it 'should require status code' do
- @task[:status] = nil
- lambda { @task.save! }.should raise_error(ActiveRecord::RecordInvalid)
+ it 'should change to completed if owner specified' do
+ @task.owner = person('assaf')
+ @task.status = :completed
+ @task.should have(:no).errors_on(:status)
end
- it 'should be protected attribute' do
- Task.new(:status=>:completed).status.should eql(:active)
- lambda { @task.update_attributes! :status=>:completed }.should_not change { @task.status }
+ it 'should switch to cancelled if previoulsy active' do
+ lambda { @task.status = :cancelled ; @task.save! }.should change(@task, :status).to(:cancelled)
+ end
+
+ it 'should switch to suspended if previously active' do
+ lambda { @task.status = :suspended ; @task.save! }.should change(@task, :status).to(:suspended)
+ end
+
+ it 'should switch to active if previously suspended' do
+ @task.status = :suspended ; @task.save!
+ lambda { @task.status = :active ; @task.save! }.should change(@task, :status).to(:active)
+ end
+
+ it 'should be protected' do
+ lambda { @task.update_attributes! :status=>:suspended }.should_not change(@task, :status)
+ end
+
+ it 'should use suspended = to flip between active and suspended' do
+ lambda { @task.update_attributes! :suspended=>true }.should change(@task, :status).to(:suspended)
+ lambda { @task.update_attributes! :suspended=>false }.should change(@task, :status).to(:active)
end
it 'should resolve symbol to index value' do
@@ -83,6 +130,17 @@
end
end
+ it 'should not allow any other value from constructor' do
+ (Task::STATUSES - [:reserved, :active]).each do |status|
+ Task.new(:owner=>person('owner'), :status=>status).should be_active
+ end
+ end
+
+ it 'should change from reserved to active when doing mass assignment' do
+ task = Task.reserve!(person('admin'))
+ lambda { task.update_attributes(:title=>'Change to active') }.should change(task, :status).to(:active)
+ end
+
end
@@ -90,35 +148,45 @@
include Specs::Tasks
before :each do
- @task = Task.new
+ @task = Task.new(default_task)
end
it 'should default to 1' do
@task.priority.should be(1)
end
- it 'should allow values from 1 to 5' do
- priorities = Array.new(7) { |i| i }
- priorities.map { |p| @task.update_attributes :priority=>p }.should eql([false] + [true] * 5 + [false])
+ it 'should allow values from 1 to 3' do
+ priorities = Array.new(5) { |i| i }
+ priorities.map { |p| @task.update_attributes :priority=>p }.should eql([false] + [true] * 3 + [false])
end
it 'should accept string value' do
- lambda { @task.update_attributes! :priority=>'4' }.should change(@task, :priority).to(4)
+ lambda { @task.update_attributes! :priority=>'2' }.should change(@task, :priority).to(2)
end
it 'should accept nil and reset to default' do
- @task.priority = 4
+ @task.priority = 2
lambda { @task.update_attributes! :priority=>nil }.should change(@task, :priority).to(1)
end
end
+describe Task, 'title' do
+ include Specs::Tasks
+
+ it 'should be required' do
+ Task.new(default_task.except(:title)).should have(1).error_on(:title)
+ end
+
+end
+
+
describe Task, 'due_on' do
include Specs::Tasks
before :each do
- @task = Task.new
+ @task = Task.new(default_task)
end
it 'should default to nil' do
@@ -155,59 +223,46 @@
describe Task, 'url', :shared=>true do
- before :each do
- @task = Task.new
- end
-
- it 'should be optional' do
- lambda { @task.save! }.should_not raise_error
- end
-
it 'should be tested for validity' do
- lambda { @task.update_attributes! @field=>'http://+++' }.should raise_error(ActiveRecord::RecordInvalid, /URL/)
+ Task.new(@field=>'http://+++').should have(1).error_on(@field)
end
it 'should allow HTTP URLS' do
- lambda { @task.update_attributes! @field=>'http://test.host/do' }.should_not raise_error
+ Task.new(@field=>'http://test.host/do').should have(:no).errors_on(@field)
end
it 'should allow HTTPS URLS' do
- lambda { @task.update_attributes! @field=>'https://test.host/do' }.should_not raise_error
+ Task.new(@field=>'https://test.host/do').should have(:no).errors_on(@field)
end
it 'should not allow other URL schemes' do
- lambda { @task.update_attributes! @field=>'ftp://test.host/do' }.should raise_error(ActiveRecord::RecordInvalid, /URL/)
+ Task.new(@field=>'ftp://test.host/do').should have(1).error_on(@field)
end
it 'should store normalized URL' do
- lambda { @task.update_attributes! @field=>'HTTP://Test.Host/Foo' }.should change(@task, @field).to('http://test.host/Foo')
- lambda { @task.update_attributes! @field=>'http://test.host' }.should change(@task, @field).to('http://test.host/')
+ task = Task.new(@field=>'HTTP://Test.Host/Foo')
+ task.should have(:no).errors_on(@field)
+ task.send(@field).should eql('http://test.host/Foo')
end
it 'should be modifiable' do
- lambda { @task.update_attributes! @field=>'http://test.host/' }.should change(@task, @field).from(nil).to('http://test.host/')
+ task = Task.new(@field=>'http://test.host/view')
+ lambda { task.update_attributes @field=>'http://test.host/' }.should change(task, @field).to('http://test.host/')
end
end
-describe Task, 'form_url' do
+describe Task, 'frame_url' do
include Specs::Tasks
it_should_behave_like 'Task url'
before :all do
- @field = :form_url
+ @field = :frame_url
end
-end
-
-
-describe Task, 'view_url' do
- include Specs::Tasks
- it_should_behave_like 'Task url'
-
- before :all do
- @field = :view_url
+ it 'should be required for active task' do
+ Task.new.should have(1).errors_on(:frame_url)
end
end
@@ -221,6 +276,10 @@
@field = :outcome_url
end
+ it 'should be optional' do
+ Task.new.should have(:no).errors_on(:outcome_url)
+ end
+
end
@@ -228,53 +287,52 @@
include Specs::Tasks
def outcome_values(mime_type)
- { :outcome_url=>'http://test.host/outcome', :outcome_type=>mime_type }
+ default_task.merge(:outcome_url=>'http://test.host/outcome', :outcome_type=>mime_type)
end
it 'should be ignored unless outcome URL specified' do
- task = Task.create!(:outcome_type=>Mime::XML)
+ task = Task.create!(outcome_values(Mime::XML).except(:outcome_url))
Task.find(task.id).outcome_type.should be_nil
end
it 'should default to Mime::XML' do
task = Task.create!(outcome_values(nil))
- Task.find(task.id).outcome_type.should be(Mime::XML)
+ Task.find(task.id).outcome_type.should eql(Mime::XML.to_s)
end
it 'should accept Mime::XML' do
task = Task.create!(outcome_values(Mime::XML))
- Task.find(task.id).outcome_type.should be(Mime::XML)
+ Task.find(task.id).outcome_type.should eql(Mime::XML.to_s)
end
it 'should accept Mime::JSON' do
task = Task.create!(outcome_values(Mime::JSON))
- Task.find(task.id).outcome_type.should be(Mime::JSON)
+ Task.find(task.id).outcome_type.should eql(Mime::JSON.to_s)
end
it 'should accept all applicable MIME types' do
Task::OUTCOME_MIME_TYPES.each do |mime_type|
task = Task.create!(outcome_values(mime_type))
- Task.find(task.id).outcome_type.should be(mime_type)
+ Task.find(task.id).outcome_type.should eql(mime_type.to_s)
end
end
it 'should accept all applicable MIME types as content type' do
Task::OUTCOME_MIME_TYPES.each do |mime_type|
task = Task.create!(outcome_values(mime_type.to_s))
- Task.find(task.id).outcome_type.should be(mime_type)
+ Task.find(task.id).outcome_type.should eql(mime_type.to_s)
end
end
it 'should accept all applicable MIME types as extension name' do
Task::OUTCOME_MIME_TYPES.each do |mime_type|
task = Task.create!(outcome_values(mime_type.to_sym.to_s))
- Task.find(task.id).outcome_type.should be(mime_type)
+ Task.find(task.id).outcome_type.should eql(mime_type.to_s)
end
end
it 'should reject unsupported MIME types' do
- lambda { Task.create!(outcome_values(Mime::ATOM)) }.
- should raise_error(ActiveRecord::RecordInvalid)
+ Task.new(outcome_values(Mime::ATOM)).should have(1).error_on(:outcome_type)
end
end
@@ -284,7 +342,7 @@
include Specs::Tasks
before :each do
- @task = Task.new
+ @task = Task.create!(default_task)
end
it 'should return hash' do
@@ -295,6 +353,11 @@
@task.data = { }
end
+ it 'should accept nil' do
+ @task.data = nil
+ @task.data.should == {}
+ end
+
it 'should be hash with indifferent access' do
@task.update_attributes! :data=>{ :foo=>1 }
Task.find(@task.id).data[:foo].should be(1)
@@ -302,7 +365,6 @@
end
it 'should reject any other value' do
- lambda { @task.data = nil }.should raise_error(ArgumentError)
lambda { @task.data = [] }.should raise_error(ArgumentError)
lambda { @task.data = 'string' }.should raise_error(ArgumentError)
end
@@ -319,12 +381,12 @@
describe Task, 'token' do
- include Specs::Tasks, Specs::Authentication
+ include Specs::Tasks
before :each do
@creator = person('creator')
@owner = person('owner')
- @task = Task.new(:creator=>@creator, :owner=>@owner)
+ @task = Task.new(default_task.merge(:creator=>@creator, :owner=>@owner))
@creator_token = @task.token_for(@creator)
@owner_token = @task.token_for(@owner)
end
@@ -359,151 +421,121 @@
end
-describe Task, 'singular role' do
- include Specs::Tasks, Specs::Authentication
+Task::SINGULAR_ROLES.each do |role|
+ describe Task, role do
+ include Specs::Tasks
- before :all do
- @person, @other = person('person'), person('alex')
- end
+ before :all do
+ @person, @other = person('person'), person('alex')
+ end
- it 'should start as nil' do
- Task::SINGULAR_ROLES.each do |role|
+ it 'should start as nil' do
Task.new.send(role).should be_nil
end
- end
- it 'should have getter and setter methods' do
- Task::SINGULAR_ROLES.each do |role|
- task = Task.create!(role=>@person)
+ it 'should have getter and setter methods' do
+ task = Task.create!(default_task.merge(role=>@person))
Task.find(task.id).send(role).should eql(@person)
end
- end
- it 'should have checker methods' do
- Task::SINGULAR_ROLES.each do |role|
- task = Task.create!(role=>@person)
+ it 'should have checker methods' do
+ task = Task.create!(default_task.merge(role=>@person))
Task.find(task.id).send("#{role}?", @person).should be_true
end
- end
- it 'should be able to remove person' do
- Task::SINGULAR_ROLES.each do |role|
- task = Task.create!(role=>@person)
+ it 'should be able to remove person' do
+ task = Task.create!(default_task.merge(role=>@person))
lambda { task.update_attributes! role=>nil }.should change(task, role).from(@person).to(nil)
end
- end
- it 'should be able to change person' do
- Task::SINGULAR_ROLES.each do |role|
- task = Task.create!(role=>@person)
+ it 'should be able to change person' do
+ task = Task.create!(default_task.merge(role=>@person))
lambda { task.update_attributes! role=>person(@other) }.should change(task, role).from(@person).to(person(@other))
end
- end
- it 'should accept person at creation' do
- Task::SINGULAR_ROLES.each do |role|
- Task.create!(role=>@person).send(role).should eql(@person)
+ it 'should accept person at creation' do
+ Task.create!(default_task.merge(role=>@person)).send(role).should eql(@person)
end
- end
- it 'should treat blank as nil' do
- Task::SINGULAR_ROLES.each do |role|
- task = Task.create!(role=>@person)
+ it 'should treat blank as nil' do
+ task = Task.create!(default_task.merge(role=>@person))
lambda { task.update_attributes! role=>'' }.should change(task, role).from(@person).to(nil)
end
- end
- it 'should accept unknown identities but fail to save' do
- Task::SINGULAR_ROLES.each do |role|
- task = Task.create!(role=>@person)
- lambda { task.update_attributes! role=>'unknown' }.
- should raise_error(ActiveRecord::RecordInvalid, /cannot find person/i)
+ it 'should accept unknown identities but fail to save' do
+ Task.new(default_task.merge(role=>'unknown')).should have(1).error_on(role)
end
- end
+ end
end
-describe Task, 'plural role' do
- include Specs::Tasks, Specs::Authentication
+Task::PLURAL_ROLES.each do |role|
+ describe Task, role do
+ include Specs::Tasks
- before :each do
- @people = Array.new(3) { |i| person("person#{i}") }
- @task = Task.new
- end
+ before :all do
+ @people = Array.new(3) { |i| person("person#{i}") }
+ end
- def plural(role)
- role.to_s.pluralize.to_sym
- end
+ before :each do
+ @task = Task.new(default_task)
+ end
+
+ def plural(role)
+ role.to_s.pluralize.to_sym
+ end
- it 'should start as empty array' do
- Task::PLURAL_ROLES.each do |role|
+ it 'should start as empty array' do
@task.send(plural(role)).should be_empty
end
- end
- it 'should have getter and setter methods' do
- Task::PLURAL_ROLES.each do |role|
+ it 'should have getter and setter methods' do
lambda { @task.update_attributes! plural(role)=>@people }.should change(@task, plural(role)).to(@people)
end
- end
- it 'should have checker methods' do
- Task::PLURAL_ROLES.each do |role|
+ it 'should have checker methods' do
lambda { @task.send "#{plural(role)}=", @people.first }.
should change { @task.send("#{role}?", @people.first) }.to(true)
@task.send("#{role}?", @people.last).should be_false
end
- end
- it 'should be able to add person' do
- Task::PLURAL_ROLES.each do |role|
+ it 'should be able to add person' do
@task.update_attributes! plural(role)=>@people[0..-2]
lambda { @task.update_attributes! plural(role)=>@people }.should change(@task, plural(role)).
from(@people[0..-2]).to(@people)
end
- end
- it 'should be able to remove person' do
- Task::PLURAL_ROLES.each do |role|
+ it 'should be able to remove person' do
@task.update_attributes! plural(role)=>@people
lambda { @task.update_attributes! plural(role)=>@people[0..-2] }.should change(@task, plural(role)).
from(@people).to(@people[0..-2])
end
- end
- it 'should add each person only once' do
- Task::PLURAL_ROLES.each do |role|
+ it "should add each person only once" do
@task.update_attributes! plural(role)=>[@people.first, @people.first]
@task.send(plural(role)).should eql([@people.first])
end
- end
- it 'should accept person at creation' do
- Task::PLURAL_ROLES.each do |role|
- Task.create!(plural(role)=>@people).send(plural(role)).should eql(@people)
+ it "should accept person at creation" do
+ Task.create!(default_task.merge(plural(role)=>@people)).send(plural(role)).should eql(@people)
end
- end
- it 'should treat blank as empty' do
- Task::PLURAL_ROLES.each do |role|
+ it "should treat blank as empty" do
@task.update_attributes! plural(role)=>@people
lambda { @task.update_attributes! plural(role)=>'' }.should change(@task, plural(role)).from(@people).to([])
end
- end
- it 'should accept unknown identities but fail to save' do
- Task::PLURAL_ROLES.each do |role|
- lambda { @task.update_attributes! plural(role)=>(@people << 'unknown') }.
- should raise_error(ActiveRecord::RecordInvalid, /cannot find person/i)
+ it "should accept unknown identities for but fail to save" do
+ Task.new(default_task.merge(plural(role)=>(@people + ['unknown']))).should have(1).error_on(role)
end
- end
+ end
end
describe Task, 'creator' do
- include Specs::Authentication, Specs::Tasks
+ include Specs::Tasks
it 'should be singular role' do
Task::SINGULAR_ROLES.should include(:creator)
@@ -526,19 +558,40 @@
it 'should default to no one' do
Task.new.owner.should be_nil
end
+
+ it 'should never be excluded owner' do
+ Task.new(:owner=>person('owner'), :excluded_owners=>people('owner', 'foo')).should have(1).error_on(:owner)
+ end
end
+describe Task, 'potential owners' do
+ include Specs::Tasks
+
+ it 'should never include excluded owners' do
+ task = Task.new(default_task.merge(:potential_owners=>people('foo', 'bar', 'baz'), :excluded_owners=>people('bar', 'qoo')))
+ task.should be_valid
+ task.potential_owners.should eql(people('foo', 'baz'))
+ task.excluded_owners.should eql(people('bar', 'qoo'))
+ end
+
+end
+
+
describe Task, 'stakeholder?' do
- include Specs::Tasks, Specs::Authentication
+ include Specs::Tasks
before :all do
@task = Task.new(@roles = all_roles)
+ @task.excluded_owners = [person('excluded'), @task.potential_owners[1]]
+ @task.save
end
it 'should return true if person associated with task' do
- @roles.except(:excluded_owners).each { |role, person| @task.stakeholder?(person).should be_true }
+ allowed = @roles.map { |role, people| Array(people) }.flatten - @task.excluded_owners
+ allowed.size.should > 0
+ allowed.each { |person| @task.stakeholder?(person).should be_true }
end
it 'should return false if person not associated with task' do
@@ -546,12 +599,11 @@
end
it 'should return true for task admin' do
- Task.admins << person(:admin)
- @task.stakeholder?(person(:admin)).should be_true
+ @task.stakeholder?(su).should be_true
end
it 'should return false for excluded owner' do
- @task.stakeholder?(@roles[:excluded_owners]).should be_false
+ @task.excluded_owners.each { |person| @task.stakeholder?(person).should be_false }
end
end
@@ -572,7 +624,7 @@
include Specs::Tasks
before :each do
- @task = Task.create!
+ @task = Task.create!(default_task)
end
it 'should start at zero' do
@@ -592,7 +644,7 @@
include Specs::Tasks
before :each do
- @task = Task.create!
+ @task = Task.create!(default_task)
end
it 'should return same value if task not udpated' do
@@ -606,7 +658,7 @@
end
it 'should be unique across tasks' do
- @task.etag.should_not eql(Task.create!)
+ @task.etag.should_not eql(Task.create!(default_task))
end
it 'should be MD5 hash' do
@@ -620,14 +672,10 @@
describe Task, 'cancellation' do
- include Specs::Authentication, Specs::Tasks
-
- before :all do
- Task.admins = @task_admins = person('admins')
- end
+ include Specs::Tasks
before :each do
- @task = Task.new(@roles = all_roles)
+ @task = Task.new(default_task.merge(@roles = all_roles))
end
it 'should default to :admin' do
@@ -639,32 +687,40 @@
end
it 'should allow admin to cancel the task for all values' do
- @roles.select { |role, person| @task.can_cancel?(person) }.map(&:first).should eql([:admins])
- @task.can_cancel?(@task_admins).should be_true
+ @roles.select { |role, people| Array(people).any? { |person| @task.can_cancel?(person) } }.
+ map(&:first).should eql([:admins])
+ @task.can_cancel?(su).should be_true
end
it 'should allow owner to cancel the task for the value :owner' do
@task.cancellation = :owner
- @roles.select { |role, person| @task.can_cancel?(person) }.map(&:first).sort_by(&:to_s).should eql([:admins, :owner])
- @task.can_cancel?(@task_admins).should be_true
+ @roles.select { |role, people| Array(people).any? { |person| @task.can_cancel?(person) } }.
+ map(&:first).sort_by(&:to_s).should eql([:admins, :owner])
+ @task.can_cancel?(su).should be_true
end
end
describe Task, 'completion' do
- include Specs::Authentication, Specs::Tasks
+ include Specs::Tasks
before :all do
- Task.admins = @task_admins = person('admins')
+ @roles = all_roles
end
before :each do
- @task = Task.new(@roles = all_roles)
+ @task = Task.create(default_task.merge(@roles))
end
it 'should allow owner to complete task' do
- @roles.select { |role, person| @task.can_complete?(person) }.map(&:first).should eql([:owner])
+ @roles.select { |role, people| Array(people).any? { |person| @task.can_complete?(person) } }.
+ map(&:first).should eql([:owner])
+ end
+
+ it 'should not validate if completed without owner' do
+ @task.status = :completed
+ lambda { @task.owner = nil }.should change { @task.valid? }.to(false)
end
end
Modified: ode/sandbox/singleshot/spec/views/sessions/show_spec.rb
URL: http://svn.apache.org/viewvc/ode/sandbox/singleshot/spec/views/sessions/show_spec.rb?rev=603406&r1=603405&r2=603406&view=diff
==============================================================================
--- ode/sandbox/singleshot/spec/views/sessions/show_spec.rb (original)
+++ ode/sandbox/singleshot/spec/views/sessions/show_spec.rb Tue Dec 11 15:14:39 2007
@@ -4,12 +4,14 @@
it 'should render login form' do
render '/sessions/show'
- response.should have_tag('div.login') do
+ response.should have_tag('form.login') do
with_tag 'form[method=post][action=?]', session_url do
- with_tag 'input[name=login][type=text]'
- with_tag 'input[name=password][type=password]'
- with_tag 'input[type=submit], button'
- without_tag('p.error')
+ with_tag 'fieldset' do
+ with_tag 'input[name=login][type=text]'
+ with_tag 'input[name=password][type=password]'
+ with_tag 'button', 'Login'
+ without_tag('p.error')
+ end
end
end
end
@@ -17,14 +19,14 @@
it 'should render flash[:error] inside login box' do
flash[:error] = 'Error message'
render '/sessions/show'
- response.should have_tag('div.login') do
+ response.should have_tag('form.login fieldset') do
with_tag 'p.error', 'Error message'
end
end
it 'should not render empty container without flash[:error]' do
render '/sessions/show'
- response.should have_tag('div.login') do
+ response.should have_tag('form.login fieldset') do
without_tag('p.error')
end
end