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 2008/05/29 01:02:16 UTC
svn commit: r661136 - in /ode/sandbox/singleshot: app/helpers/ app/models/
app/views/tasks/ db/ db/migrate/ lib/tasks/ public/stylesheets/ spec/
spec/models/
Author: assaf
Date: Wed May 28 16:02:15 2008
New Revision: 661136
URL: http://svn.apache.org/viewvc?rev=661136&view=rev
Log:
Added form_perform_url and form_view_url, both of which are optional (not all tasks have forms).
Added form_completing which decides whether form completes task, or we need to include a button to mark task as completed.
Modified:
ode/sandbox/singleshot/app/helpers/task_helper.rb
ode/sandbox/singleshot/app/models/task.rb
ode/sandbox/singleshot/app/views/tasks/show.html.erb
ode/sandbox/singleshot/db/migrate/20080506015046_create_tasks.rb
ode/sandbox/singleshot/db/schema.rb
ode/sandbox/singleshot/lib/tasks/populate.rake
ode/sandbox/singleshot/public/stylesheets/default.css
ode/sandbox/singleshot/spec/common.rb
ode/sandbox/singleshot/spec/models/task_spec.rb
Modified: ode/sandbox/singleshot/app/helpers/task_helper.rb
URL: http://svn.apache.org/viewvc/ode/sandbox/singleshot/app/helpers/task_helper.rb?rev=661136&r1=661135&r2=661136&view=diff
==============================================================================
--- ode/sandbox/singleshot/app/helpers/task_helper.rb (original)
+++ ode/sandbox/singleshot/app/helpers/task_helper.rb Wed May 28 16:02:15 2008
@@ -15,12 +15,15 @@
vitals.to_sentence
end
- def task_iframe_url(task, person = authenticated)
- task_uri = URI(task_perform_url(task))
- task_uri.user, task_uri.password = '_token', task.token_for(person)
- uri = URI(task.frame_url)
- uri.query = CGI.parse(uri.query || '').update('perform'=>task.owner?(person), 'task_url'=>task_uri).to_query
- uri.to_s
+ def task_frame(task)
+ if task.form_perform_url
+ task_uri = URI(task_perform_url(task))
+ task_uri.user, task_uri.password = '_token', task.token_for(authenticated)
+ uri = URI(task.owner?(authenticated) ? task.form_perform_url : (task.form_view_url || task.form_perform_url))
+ uri.query = CGI.parse(uri.query || '').update('perform'=>task.owner?(authenticated), 'task_url'=>task_uri).to_query
+ uri.to_s
+ content_tag 'iframe', '', :id=>'task_frame', :src=>uri.to_s
+ end
end
end
Modified: ode/sandbox/singleshot/app/models/task.rb
URL: http://svn.apache.org/viewvc/ode/sandbox/singleshot/app/models/task.rb?rev=661136&r1=661135&r2=661136&view=diff
==============================================================================
--- ode/sandbox/singleshot/app/models/task.rb (original)
+++ ode/sandbox/singleshot/app/models/task.rb Wed May 28 16:02:15 2008
@@ -3,20 +3,22 @@
#
# Table name: tasks
#
-# id :integer not null, primary key
-# title :string(255) not null
-# description :string(255) not null
-# priority :integer(1) not null
-# due_on :date
-# status :string(255) not null
-# frame_url :string(255)
-# outcome_url :string(255)
-# outcome_type :string(255)
-# access_key :string(32)
-# data :text not null
-# version :integer default(0), not null
-# created_at :datetime
-# updated_at :datetime
+# id :integer not null, primary key
+# title :string(255) not null
+# description :string(255) not null
+# priority :integer(1) not null
+# due_on :date
+# status :string(255) not null
+# form_view_url :string(255)
+# form_perform_url :string(255)
+# form_completing :boolean
+# outcome_url :string(255)
+# outcome_type :string(255)
+# access_key :string(32)
+# data :text not null
+# version :integer default(0), not null
+# created_at :datetime
+# updated_at :datetime
#
require 'openssl'
@@ -107,28 +109,32 @@
# -- Common task attributes --
- #
- validates_presence_of :title, :frame_url
- validates_url :frame_url, :if=>:frame_url
+ validates_presence_of :title
- # -- View and perform ---
+ # -- View and perform ---
- # --- Task data ---
+ validates_url :form_perform_url, :if=>:form_perform_url
+ validates_url :form_view_url, :if=>:form_view_url
- def data
- return self[:data] if Hash === self[:data]
- self[:data] = ActiveSupport::JSON.decode(self[:data] || '')
+ before_validation do |record|
+ unless record.form_perform_url
+ record.form_view_url = nil
+ record.form_completing = nil
+ end
end
- def data=(data)
- raise ArgumentError, 'Must be a hash or nil' unless Hash === data || data.nil?
- self[:data] = data || {}
+
+ # --- Task data ---
+
+ serialize :data
+ before_validation do |record|
+ record.data ||= {}
end
- before_save do |task|
- task[:data] = task[:data].to_json if task[:data]
+ validate do |record|
+ record.errors.add :data, 'Must be a hash' unless Hash === record.data
end
@@ -163,7 +169,7 @@
end
def over_due?
- due_on && due_on < Date.today
+ due_on ? due_on < Date.today : false
end
# Scopes can use this to add ranking methods on returned records.
Modified: ode/sandbox/singleshot/app/views/tasks/show.html.erb
URL: http://svn.apache.org/viewvc/ode/sandbox/singleshot/app/views/tasks/show.html.erb?rev=661136&r1=661135&r2=661136&view=diff
==============================================================================
--- ode/sandbox/singleshot/app/views/tasks/show.html.erb (original)
+++ ode/sandbox/singleshot/app/views/tasks/show.html.erb Wed May 28 16:02:15 2008
@@ -1,42 +1,44 @@
<% div_for @task do %>
<div class='bar'>
<div class='summary'>
- <div class='vitals'><%= task_vitals(@task) %></div>
- <div class='actions'><%= quick_actions(@task) %> <%= content_tag 'button', 'â½ More Options', :onclick=>"Singleshot.expand(event, '.expanded', 'â³ Less options')", :class=>'button-to' %></div>
- </div>
- <div class='expanded' style='display:none'>
- <%= link_to image_tag('calendar.png') + ' Calendar', formatted_task_url(@task, 'ics', :access_key=>authenticated.access_key),
- :rel=>'alternate', :title=>'Add this task to your calendar' %>
- <%= link_to image_tag('feed.png') + ' Activity', formatted_activity_url(@task, 'atom', :access_key=>authenticated.access_key),
- :rel=>'alternate', :title=>'Subscribe to see changes to this task' %>
- <h2><%= h(@task.title) %></h2>
- <div class='description'><%= sanitize(simple_format(@task.description)) %></div>
- <dl>
- <dt>Priority</dt><dd><%= ['High', 'Medium', 'Low'][@task.priority - 1] %></dd>
- <%= content_tag('dt', 'Due on') + content_tag('dd', relative_date(@task.due_on)) if @task.due_on %>
- <dt>Recent activity</dt>
- <dd>
- <ol class='activities hfeed'>
- <% for activity in @task.activities %>
- <% content_tag_for 'li', activity, :class=>'hentry entry-title' do %>
- <%= link_to activity.person.fullname, activity.person.identity %>
- <%= activity.action %>
- <%= link_to activity.task.title, task_url(activity.task), :rel=>'bookmark' %>
+ <div class='vitals'><%= task_vitals(@task) %></div>
+ <div class='actions'><%= quick_actions(@task) %> <%= content_tag 'button', 'â½ More Options', :onclick=>"Singleshot.expand(event, '.expanded', 'â³ Less options')", :class=>'button-to' %></div>
+ </div>
+ <div class='expanded' style='display:none'>
+ <%= link_to image_tag('calendar.png') + ' Calendar', formatted_task_url(@task, 'ics', :access_key=>authenticated.access_key),
+ :rel=>'alternate', :title=>'Add this task to your calendar' %>
+ <%= link_to image_tag('feed.png') + ' Activity', formatted_activity_url(@task, 'atom', :access_key=>authenticated.access_key),
+ :rel=>'alternate', :title=>'Subscribe to see changes to this task' %>
+ <h2><%= h(@task.title) %></h2>
+ <dl>
+ <dt>Priority</dt><dd><%= ['High', 'Medium', 'Low'][@task.priority - 1] %></dd>
+ <%= content_tag('dt', 'Due on') + content_tag('dd', relative_date(@task.due_on)) if @task.due_on %>
+ <dt>Recent activity</dt>
+ <dd>
+ <ol class='activities hfeed'>
+ <% for activity in @task.activities %>
+ <% content_tag_for 'li', activity, :class=>'hentry entry-title' do %>
+ <%= link_to activity.person.fullname, activity.person.identity %>
+ <%= activity.action %>
+ <%= link_to activity.task.title, task_url(activity.task), :rel=>'bookmark' %>
+ <% end %>
<% end %>
- <% end %>
- </ol>
- </dd>
- <%= admins = @task.admins.map { |person| link_to_person(person, :admin) }
- content_tag('dt', 'Admins') + content_tag('dd', admins.to_sentence) unless admins.empty? %>
- <%= observers = @task.observers.map { |person| link_to_person(person, :observer) }
- content_tag('dt', 'Observers') + content_tag('dd', observers.to_sentence) unless observers.empty? %>
- </dl>
- <div class='actions'>
- <%= quick_actions(@task) %>
+ </ol>
+ </dd>
+ <%= admins = @task.admins.map { |person| link_to_person(person, :admin) }
+ content_tag('dt', 'Admins') + content_tag('dd', admins.to_sentence) unless admins.empty? %>
+ <%= observers = @task.observers.map { |person| link_to_person(person, :observer) }
+ content_tag('dt', 'Observers') + content_tag('dd', observers.to_sentence) unless observers.empty? %>
+ </dl>
+ <div class='actions'>
+ <%= quick_actions(@task) %>
+ </div>
</div>
</div>
-
- </div>
- <%= content_tag 'iframe', nil, :id=>'task_frame', :src=>task_iframe_url(@task) %>
+ <div class='description'><%= sanitize(simple_format(@task.description)) %></div>
+ <%= task_frame @task %>
+ <% unless @task.form_completing %>
+ <div class='completion'><div class='actions'><%= button_to 'Completed', task_url(@task, :status=>'completed'), :title=>'Click when task completed' %></div></div>
+ <% end %>
<%= javascript_tag 'Singleshot.taskView()' %>
<% end %>
Modified: ode/sandbox/singleshot/db/migrate/20080506015046_create_tasks.rb
URL: http://svn.apache.org/viewvc/ode/sandbox/singleshot/db/migrate/20080506015046_create_tasks.rb?rev=661136&r1=661135&r2=661136&view=diff
==============================================================================
--- ode/sandbox/singleshot/db/migrate/20080506015046_create_tasks.rb (original)
+++ ode/sandbox/singleshot/db/migrate/20080506015046_create_tasks.rb Wed May 28 16:02:15 2008
@@ -6,7 +6,9 @@
t.integer 'priority', :null=>false, :limit=>1
t.date 'due_on', :null=>true
t.string 'status', :null=>false
- t.string 'frame_url', :null=>true
+ t.string 'form_view_url'
+ t.string 'form_perform_url'
+ t.boolean 'form_completing'
t.string 'outcome_url', :null=>true
t.string 'outcome_type', :null=>true
t.string 'access_key', :null=>true, :limit=>32
Modified: ode/sandbox/singleshot/db/schema.rb
URL: http://svn.apache.org/viewvc/ode/sandbox/singleshot/db/schema.rb?rev=661136&r1=661135&r2=661136&view=diff
==============================================================================
--- ode/sandbox/singleshot/db/schema.rb (original)
+++ ode/sandbox/singleshot/db/schema.rb Wed May 28 16:02:15 2008
@@ -43,17 +43,19 @@
end
create_table "tasks", :force => true do |t|
- t.string "title", :null => false
- t.string "description", :null => false
- t.integer "priority", :limit => 1, :null => false
+ t.string "title", :null => false
+ t.string "description", :null => false
+ t.integer "priority", :limit => 1, :null => false
t.date "due_on"
- t.string "status", :null => false
- t.string "frame_url"
+ t.string "status", :null => false
+ t.string "form_view_url"
+ t.string "form_perform_url"
+ t.boolean "form_completing"
t.string "outcome_url"
t.string "outcome_type"
- t.string "access_key", :limit => 32
- t.text "data", :null => false
- t.integer "version", :default => 0, :null => false
+ t.string "access_key", :limit => 32
+ t.text "data", :null => false
+ t.integer "version", :default => 0, :null => false
t.datetime "created_at"
t.datetime "updated_at"
end
Modified: ode/sandbox/singleshot/lib/tasks/populate.rake
URL: http://svn.apache.org/viewvc/ode/sandbox/singleshot/lib/tasks/populate.rake?rev=661136&r1=661135&r2=661136&view=diff
==============================================================================
--- ode/sandbox/singleshot/lib/tasks/populate.rake (original)
+++ ode/sandbox/singleshot/lib/tasks/populate.rake Wed May 28 16:02:15 2008
@@ -36,7 +36,7 @@
retract
you = Person.find_by_identity(ENV['USER'])
defaults = { :title=>Faker::Lorem.sentence, :description=>Faker::Lorem.paragraphs(3).join("\n\n"),
- :frame_url=>'http://localhost:3001/sandwich', :potential_owners=>[you, other] }
+ :form_perform_url=>'http://localhost:3001/sandwich', :form_completing=>true, :potential_owners=>[you, other] }
returning Task.new(defaults.merge(attributes || {})) do |task|
task.modified_by(you).save!
end
Modified: ode/sandbox/singleshot/public/stylesheets/default.css
URL: http://svn.apache.org/viewvc/ode/sandbox/singleshot/public/stylesheets/default.css?rev=661136&r1=661135&r2=661136&view=diff
==============================================================================
--- ode/sandbox/singleshot/public/stylesheets/default.css (original)
+++ ode/sandbox/singleshot/public/stylesheets/default.css Wed May 28 16:02:15 2008
@@ -316,9 +316,6 @@
font-size: 1.2em;
margin: 0 0 1em 0;
}
-div.task div.bar div.expanded div.description {
- margin: 1em 0 1em 0;
-}
div.task div.bar div.expanded dl {
}
div.task div.bar div.expanded dt {
@@ -337,12 +334,16 @@
text-align: right;
}
+div.task div.description {
+ padding: 3em 3em 1em 3em;
+}
+
div.task iframe {
border: 0;
width: 100%;
height: 0;
padding: 0;
- margin: 3em 0 0 0;
+ margin: 0;
background: transparent;
}
Modified: ode/sandbox/singleshot/spec/common.rb
URL: http://svn.apache.org/viewvc/ode/sandbox/singleshot/spec/common.rb?rev=661136&r1=661135&r2=661136&view=diff
==============================================================================
--- ode/sandbox/singleshot/spec/common.rb (original)
+++ ode/sandbox/singleshot/spec/common.rb Wed May 28 16:02:15 2008
@@ -51,7 +51,6 @@
def default_task(with = {})
{ :title=>'Test this',
- :frame_url=>'http://test.host/fill_me',
:outcome_url=>'http://test.host/outcome' }.merge(with)
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=661136&r1=661135&r2=661136&view=diff
==============================================================================
--- ode/sandbox/singleshot/spec/models/task_spec.rb (original)
+++ ode/sandbox/singleshot/spec/models/task_spec.rb Wed May 28 16:02:15 2008
@@ -1,285 +1,363 @@
require File.dirname(__FILE__) + '/../spec_helper'
-describe Task, 'to_param' do
+describe Task do
include Specs::Tasks
- it 'should return nil unless task exists in database' do
- Task.new.to_param.should be_nil
- end
+ describe 'to_param' do
- it 'should begin with task ID' do
- Task.create!(default_task).to_param.to_i.should == Task.last.id
- end
+ it 'should return nil unless task exists in database' do
+ Task.new.to_param.should be_nil
+ end
- it 'should include task title' do
- Task.create!(default_task.merge(:title=>'Task Title')).to_param[/^\d+-(.*)/, 1].should == 'Task-Title'
- end
+ it 'should begin with task ID' do
+ Task.create!(default_task).to_param.to_i.should == Task.last.id
+ end
- it 'should properly encode task title' do
- Task.create!(default_task.merge(:title=>'Test:encoding, ignoring "unprintable" characters')).
- to_param[/^\d+-(.*)/, 1].should == 'Test-encoding-ignoring-unprintable-characters'
- end
+ it 'should include task title' do
+ Task.create!(default_task.merge(:title=>'Task Title')).to_param[/^\d+-(.*)/, 1].should == 'Task-Title'
+ end
- it 'should remove redundant hyphens' do
- Task.create!(default_task.merge(:title=>'-Test redundant--hyphens--')).to_param[/^\d+-(.*)/, 1].should == 'Test-redundant-hyphens'
- end
+ it 'should properly encode task title' do
+ Task.create!(default_task.merge(:title=>'Test:encoding, ignoring "unprintable" characters')).
+ to_param[/^\d+-(.*)/, 1].should == 'Test-encoding-ignoring-unprintable-characters'
+ end
- it 'should deal gracefully with missing title' do
- Task.create!(default_task.merge(:title=>'--')).to_param.should =~ /^\d+$/
- end
+ it 'should remove redundant hyphens' do
+ Task.create!(default_task.merge(:title=>'-Test redundant--hyphens--')).to_param[/^\d+-(.*)/, 1].should == 'Test-redundant-hyphens'
+ end
+
+ it 'should deal gracefully with missing title' do
+ Task.create!(default_task.merge(:title=>'--')).to_param.should =~ /^\d+$/
+ end
+
+ it 'should leave UTF-8 text alone' do
+ Task.create!(default_task.merge(:title=>'jösé')).to_param[/^\d+-(.*)/, 1].should == 'jösé'
+ end
- it 'should leave UTF-8 text alone' do
- Task.create!(default_task.merge(:title=>'jösé')).to_param[/^\d+-(.*)/, 1].should == 'jösé'
end
-end
+ describe 'version' do
-describe Task, 'version' do
- include Specs::Tasks
+ it 'should begin at zero' do
+ Task.create!(default_task).version.should == 0
+ end
- it 'should begin at zero' do
- Task.create!(default_task).version.should == 0
+ it 'should increment each time task is updated' do
+ Task.create! default_task
+ lambda { Task.last.update_attributes :priority=>1 }.should change { Task.last.version }.from(0).to(1)
+ lambda { Task.last.update_attributes :due_on=>Time.now }.should change { Task.last.version }.from(1).to(2)
+ end
end
- it 'should increment each time task is updated' do
- Task.create! default_task
- lambda { Task.last.update_attributes :priority=>1 }.should change { Task.last.version }.from(0).to(1)
- lambda { Task.last.update_attributes :due_on=>Time.now }.should change { Task.last.version }.from(1).to(2)
- end
-end
+ describe 'etag' do
-describe Task, 'etag' do
- include Specs::Tasks
+ it 'should be hex digest' do
+ Task.create!(default_task).etag.should =~ /^[0-9a-f]{32}$/
+ end
- it 'should be hex digest' do
- Task.create!(default_task).etag.should =~ /^[0-9a-f]{32}$/
- end
+ it 'should remain the same if task not modified' do
+ Task.create! default_task
+ Task.last.etag.should == Task.last.etag
+ end
- it 'should remain the same if task not modified' do
- Task.create! default_task
- Task.last.etag.should == Task.last.etag
- end
+ it 'should be different for two different tasks' do
+ Task.create!(default_task).etag.should_not == Task.create(default_task).etag
+ end
- it 'should be different for two different tasks' do
- Task.create!(default_task).etag.should_not == Task.create(default_task).etag
- end
+ it 'should change whenever task is saved' do
+ Task.create! default_task
+ lambda { Task.last.update_attributes! :priority=>1 }.should change { Task.last.etag }
+ lambda { Task.last.update_attributes! :due_on=>Time.now }.should change { Task.last.etag }
+ end
- it 'should change whenever task is saved' do
- Task.create! default_task
- lambda { Task.last.update_attributes! :priority=>1 }.should change { Task.last.etag }
- lambda { Task.last.update_attributes! :due_on=>Time.now }.should change { Task.last.etag }
end
-end
+ describe 'status' do
-describe Task, 'status' do
- include Specs::Tasks
+ def task_with_status(status, attributes = nil)
+ attributes ||= {}
+ task = case status
+ when 'active'
+ Task.create!(default_task.merge(attributes).merge(:status=>status, :owner=>person('owner')))
+ when 'completed'
+ active = Task.create!(default_task.merge(attributes).merge(:status=>'active', :owner=>person('owner')))
+ active.update_attributes :status=>'completed'
+ active
+ else
+ Task.create!(default_task.merge(attributes).merge(:status=>status))
+ end
- def task_with_status(status, attributes = nil)
- attributes ||= {}
- task = case status
- when 'active'
- Task.create!(default_task.merge(attributes).merge(:status=>status, :owner=>person('owner')))
- when 'completed'
- active = Task.create!(default_task.merge(attributes).merge(:status=>'active', :owner=>person('owner')))
- active.update_attributes :status=>'completed'
- active
- else
- Task.create!(default_task.merge(attributes).merge(:status=>status))
+ def task.transition_to(status, attributes = nil)
+ attributes ||= {}
+ update_attributes attributes.merge(:status=>status)
+ self
+ end
+ def task.can_transition?(status, attributes = nil)
+ transition_to(status, attributes).errors_on(:status).empty?
+ end
+ task
end
- def task.transition_to(status, attributes = nil)
- attributes ||= {}
- update_attributes attributes.merge(:status=>status)
- self
+ it 'should start as ready' do
+ Task.create!(default_task).status.should == 'ready'
end
- def task.can_transition?(status, attributes = nil)
- transition_to(status, attributes).errors_on(:status).empty?
+
+ it 'should only accept supported value' do
+ Task.create(:status=>'unsupported').should have(1).error_on(:status)
end
- task
- end
- it 'should start as ready' do
- Task.create!(default_task).status.should == 'ready'
- end
+ it 'should allow starting in reserved' do
+ Task.create!(default_task.merge(:status=>'reserved')).status.should == 'reserved'
+ end
- it 'should only accept supported value' do
- Task.create(:status=>'unsupported').should have(1).error_on(:status)
- end
+ it 'should not transition to reserved from any other status' do
+ for status in Task::STATUSES - ['reserved']
+ task_with_status(status).can_transition?('reserved').should be_false
+ end
+ end
- it 'should allow starting in reserved' do
- Task.create!(default_task.merge(:status=>'reserved')).status.should == 'reserved'
- end
+ it 'should start as ready if started as active but not associated with owner' do
+ Task.create!(default_task.merge(:status=>'active')).status.should == 'ready'
+ end
- it 'should not transition to reserved from any other status' do
- for status in Task::STATUSES - ['reserved']
- task_with_status(status).can_transition?('reserved').should be_false
+ it 'should start as active if started as ready and associated with owner' do
+ Task.create!(default_task.merge(:owner=>person('owner'))).status.should == 'active'
end
- end
- it 'should start as ready if started as active but not associated with owner' do
- Task.create!(default_task.merge(:status=>'active')).status.should == 'ready'
- end
+ it 'should start as active if started as ready and associated with one potential owner' do
+ Task.create!(default_task.merge(:potential_owners=>people('owner'))).status.should == 'active'
+ end
- it 'should start as active if started as ready and associated with owner' do
- Task.create!(default_task.merge(:owner=>person('owner'))).status.should == 'active'
- end
+ it 'should start as ready if started as ready and associated with several potential owners' do
+ Task.create!(default_task.merge(:potential_owners=>people('foo', 'bar'))).status.should == 'ready'
+ end
- it 'should start as active if started as ready and associated with one potential owner' do
- Task.create!(default_task.merge(:potential_owners=>people('owner'))).status.should == 'active'
- end
+ it 'should transition from ready to active when associated with owner' do
+ task = task_with_status('ready')
+ lambda { task.update_attributes :owner=>person('owner') }.should change(task, :status).to('active')
+ end
- it 'should start as ready if started as ready and associated with several potential owners' do
- Task.create!(default_task.merge(:potential_owners=>people('foo', 'bar'))).status.should == 'ready'
- end
+ it 'should transition from active to ready when owner removed' do
+ task = task_with_status('active')
+ lambda { task.update_attributes :owner=>nil }.should change(task, :status).to('ready')
+ end
- it 'should transition from ready to active when associated with owner' do
- task = task_with_status('ready')
- lambda { task.update_attributes :owner=>person('owner') }.should change(task, :status).to('active')
- end
+ it 'should accept suspended as initial value' do
+ Task.create!(default_task.merge(:status=>'suspended')).status.should == 'suspended'
+ end
- it 'should transition from active to ready when owner removed' do
- task = task_with_status('active')
- lambda { task.update_attributes :owner=>nil }.should change(task, :status).to('ready')
- end
+ it 'should transition from ready to suspended' do
+ task_with_status('ready').can_transition?('suspended').should be_true
+ end
- it 'should accept suspended as initial value' do
- Task.create!(default_task.merge(:status=>'suspended')).status.should == 'suspended'
- end
+ it 'should transition from suspended back to ready' do
+ task_with_status('suspended').transition_to('ready').status.should == 'ready'
+ task_with_status('suspended').transition_to('active').status.should == 'ready'
+ end
- it 'should transition from ready to suspended' do
- task_with_status('ready').can_transition?('suspended').should be_true
- end
+ it 'should transition from active to suspended' do
+ task_with_status('active').can_transition?('suspended').should be_true
+ end
- it 'should transition from suspended back to ready' do
- task_with_status('suspended').transition_to('ready').status.should == 'ready'
- task_with_status('suspended').transition_to('active').status.should == 'ready'
- end
+ it 'should transition from suspended back to active' do
+ task_with_status('suspended', :owner=>person('owner')).transition_to('active').status.should == 'active'
+ task_with_status('suspended', :owner=>person('owner')).transition_to('ready').status.should == 'active'
+ end
- it 'should transition from active to suspended' do
- task_with_status('active').can_transition?('suspended').should be_true
- end
+ it 'should only transition to completed from active' do
+ for status in Task::STATUSES - ['completed']
+ task_with_status(status).can_transition?('completed').should == (status =='active')
+ end
+ end
- it 'should transition from suspended back to active' do
- task_with_status('suspended', :owner=>person('owner')).transition_to('active').status.should == 'active'
- task_with_status('suspended', :owner=>person('owner')).transition_to('ready').status.should == 'active'
- end
+ it 'should not transition to completed without owner' do
+ task_with_status('active').can_transition?('completed', :owner=>nil).should be_false
+ end
- it 'should only transition to completed from active' do
- for status in Task::STATUSES - ['completed']
- task_with_status(status).can_transition?('completed').should == (status =='active')
+ it 'should not transition from completed to any other status' do
+ for status in Task::STATUSES - ['completed']
+ task_with_status('completed').can_transition?(status).should be_false
+ end
end
- end
- it 'should not transition to completed without owner' do
- task_with_status('active').can_transition?('completed', :owner=>nil).should be_false
- end
+ it 'should transition to cancelled from any other status but completed' do
+ for status in Task::STATUSES - ['cancelled']
+ task_with_status(status).can_transition?('cancelled').should == (status !='completed')
+ end
+ end
- it 'should not transition from completed to any other status' do
- for status in Task::STATUSES - ['completed']
- task_with_status('completed').can_transition?(status).should be_false
+ it 'should not transition from cancelled to any other status' do
+ for status in Task::STATUSES - ['cancelled']
+ task_with_status('cancelled').can_transition?(status).should be_false
+ end
end
- end
- it 'should transition to cancelled from any other status but completed' do
- for status in Task::STATUSES - ['cancelled']
- task_with_status(status).can_transition?('cancelled').should == (status !='completed')
+ it 'should not allow changing of completed or cancelled tasks' do
+ lambda { task_with_status('completed').update_attributes :title=>'never mind' }.should raise_error(ActiveRecord::ReadOnlyRecord)
+ lambda { task_with_status('cancelled').update_attributes :title=>'never mind' }.should raise_error(ActiveRecord::ReadOnlyRecord)
end
+
end
- it 'should not transition from cancelled to any other status' do
- for status in Task::STATUSES - ['cancelled']
- task_with_status('cancelled').can_transition?(status).should be_false
+
+ describe 'title' do
+
+ it 'should be required' do
+ Task.new(default_task.except(:title)).should have(1).error_on(:title)
+ end
+
+ it 'should not be empty' do
+ Task.new(default_task.merge(:title=>' ')).should have(1).error_on(:title)
end
- end
- it 'should not allow changing of completed or cancelled tasks' do
- lambda { task_with_status('completed').update_attributes :title=>'never mind' }.should raise_error(ActiveRecord::ReadOnlyRecord)
- lambda { task_with_status('cancelled').update_attributes :title=>'never mind' }.should raise_error(ActiveRecord::ReadOnlyRecord)
end
-end
+ describe 'priority' do
-=begin
-describe Task, 'priority' do
- include Specs::Tasks
+ it 'should default to 2' do
+ Task.create(default_task.except(:priority)).priority.should == 2
+ end
- it 'should default to 1' do
- Task.new.priority.should == 1
- end
+ it 'should allow values from 1 to 3' do
+ priorities = Array.new(5) { |i| i }
+ priorities.map { |p| Task.new(default_task.merge(:priority=>p)).valid? }.should eql([false] + [true] * 3 + [false])
+ end
- it 'should allow values from 1 to 3' do
- priorities = Array.new(5) { |i| i }
- priorities.map { |p| Task.new(default_task.merge(:priority=>p)).valid? }.should eql([false] + [true] * 3 + [false])
- end
+ it 'should accept string value' do
+ Task.create(default_task.merge(:priority=>'1')).priority.should == 1
+ end
- it 'should accept string value' do
- Task.create default_task
- lambda { Task.first.update_attributes! :priority=>'2' }.should change { Task.first.priority }.to(2)
- end
+ it 'should accept nil and reset to default' do
+ Task.create default_task.merge(:priority=>1)
+ lambda { Task.last.update_attributes! :priority=>nil }.should change { Task.last.priority }.to(2)
+ end
- it 'should accept nil and reset to default' do
- Task.create default_task.merge(:priority=>2)
- lambda { Task.first.update_attributes! :priority=>nil }.should change { Task.first.priority }.to(1)
end
-end
+ describe 'high_priority?' do
-describe Task, 'title' do
- include Specs::Tasks
+ it 'should be true for priority 1' do
+ Task.new(:priority=>1).high_priority?.should be_true
+ end
+
+ it 'should be false for priorities other than 1' do
+ for priority in 2..3
+ Task.new(:priority=>priority).high_priority?.should be_false
+ end
+ end
- it 'should be required' do
- Task.new(default_task.except(:title)).should have(1).error_on(:title)
end
-end
+ describe 'due_on' do
-describe Task, 'due_on' do
- include Specs::Tasks
+ it 'should not be required' do
+ Task.create(default_task.except(:due_on)).should have(:no).errors
+ end
- before :each do
- @task = Task.new(default_task)
- end
+ it 'should accept time and return date' do
+ now = Time.now
+ Task.create! default_task.merge(:due_on=>now)
+ Task.last.due_on.should == now.to_date
+ end
- it 'should not be required' do
- Task.create(default_task.except(:due_on)).should have(:no).errors
- end
+ it 'should accept date and return it' do
+ today = Date.today
+ Task.create! default_task.merge(:due_on=>today)
+ Task.last.due_on.should == today
+ end
- it 'should accept time and return date' do
- now = Time.now
- lambda { @task.update_attributes! :due_on=>now ; @task.reload }.should change(@task, :due_on).to(now.to_date)
- end
+ it 'should accept ISO 8601 date string and return date' do
+ today = Date.today
+ Task.create! default_task.merge(:due_on=>today.to_s)
+ Task.last.due_on.should == today
+ end
- it 'should accept date and return it' do
- today = Date.today
- lambda { @task.update_attributes! :due_on=>today ; @task.reload }.should change(@task, :due_on).to(today)
- end
+ it 'should accept ISO 8601 time string and return date' do
+ now = Time.now
+ Task.create! default_task.merge(:due_on=>now.iso8601)
+ Task.last.due_on.should == now.to_date
+ end
+
+ it 'should accept blank string and set to nil' do
+ Task.create! default_task.merge(:due_on=>Time.now)
+ Task.last.update_attributes :due_on=>''
+ Task.last.due_on.should be_nil
+ end
- it 'should accept ISO 8601 date string and return date' do
- today = Date.today
- lambda { @task.update_attributes! :due_on=>today.to_s ; @task.reload }.should change(@task, :due_on).to(today)
end
- it 'should accept ISO 8601 time string and return date' do
- now = Time.now
- lambda { @task.update_attributes! :due_on=>now.iso8601 ; @task.reload }.should change(@task, :due_on).to(now.to_date)
+
+ describe 'over_due?' do
+
+ it 'should be false if task has no due date' do
+ Task.new.over_due?.should be_false
+ end
+
+ it 'should be false if task due date in the future' do
+ Task.new(:due_on=>Date.tomorrow).over_due?.should be_false
+ end
+
+ it 'should be false if task due today' do
+ Task.new(:due_on=>Date.today).over_due?.should be_false
+ end
+
+ it 'should be true if task due date in the past' do
+ Task.new(:due_on=>Date.yesterday).over_due?.should be_true
+ end
+
end
- it 'should accept blank string and set to nil' do
- @task.update_attributes! :due_on=>Date.today
- lambda { @task.update_attributes! :due_on=>'' ; @task.reload }.should change(@task, :due_on).to(nil)
+
+ describe 'ranking'
+
+ describe 'modified_by'
+
+ describe 'activities'
+
+ describe 'with_stakeholders'
+
+ describe 'for_stakeholder'
+
+ describe 'data' do
+
+ it 'should be empty hash by default' do
+ Task.new.data.should == {}
+ end
+
+ it 'should return nothing for new task' do
+ Task.create default_task.except(:data)
+ Task.last.data.should == {}
+ end
+
+ it 'should accept argument for mass assignment' do
+ Task.create default_task
+ lambda { Task.last.update_attributes :data=>{'foo'=>'bar'} }.should change { Task.last.data }.to('foo'=>'bar')
+ end
+
+ it 'should accept nil' do
+ Task.create default_task.merge(:data=>{'foo'=>'bar'})
+ lambda { Task.last.update_attributes :data=>nil }.should change { Task.last.data }.to({})
+ end
+
+ it 'should reject any other value' do
+ Task.create(default_task.merge(:data=>[])).should have(1).error_on(:data)
+ Task.create(default_task.merge(:data=>'string')).should have(1).error_on(:data)
+ end
+
end
end
+=begin
+
describe Task, 'url', :shared=>true do
it 'should be tested for validity' do
@@ -397,39 +475,6 @@
end
-describe Task, 'data' do
- include Specs::Tasks
-
- before :each do
- # @task = Task.create!(default_task)
- end
-
- it 'should be empty hash by default' do
- Task.new.data.should == {}
- end
-
- it 'should return nothing for new task' do
- Task.create default_task.except(:data)
- Task.first.data.should == {}
- end
-
- it 'should accept argument from mass assignment' do
- Task.create default_task
- lambda { Task.first.update_attributes :data=>{'foo'=>'bar'} }.should change { Task.first.data }.to('foo'=>'bar')
- end
-
- it 'should accept nil' do
- Task.create default_task.merge(:data=>{'foo'=>'bar'})
- lambda { Task.first.update_attributes :data=>nil }.should change { Task.first.data }.to({})
- end
-
- it 'should reject any other value' do
- lambda { Task.create default_task.merge(:data=>[]) }.should raise_error(ArgumentError)
- lambda { Task.create default_task.merge(:data=>'string') }.should raise_error(ArgumentError)
- end
-
-end
-
describe Task, 'token' do
include Specs::Tasks