diff --git a/app/models/context.rb b/app/models/context.rb index d5e5be00..dd78f9bc 100644 --- a/app/models/context.rb +++ b/app/models/context.rb @@ -5,11 +5,32 @@ class Context < ActiveRecord::Base has_many :recurring_todos, :dependent => :delete_all belongs_to :user - scope :active, :conditions => { :hide => false } - scope :hidden, :conditions => { :hide => true } + scope :active, :conditions => { :state => :active } + scope :hidden, :conditions => { :state => :hide } acts_as_list :scope => :user, :top_of_list => 0 + # state machine + include AASM + aasm_column :state + aasm_initial_state :active + + aasm_state :active + aasm_state :closed + aasm_state :hidden + + aasm_event :close do + transitions :to => :closed, :from => [:active, :hidden], :guard => :no_active_todos? + end + + aasm_event :hide do + transitions :to => :hidden, :from => [:active, :closed] + end + + aasm_event :activate do + transitions :to => :active, :from => [:closed, :hidden] + end + attr_protected :user validates_presence_of :name, :message => "context must have a name" @@ -20,10 +41,6 @@ class Context < ActiveRecord::Base NullContext.new end - def hidden? - self.hide == true || self.hide == 1 - end - def title name end @@ -32,6 +49,10 @@ class Context < ActiveRecord::Base @new_record_before_save end + def no_active_todos? + return todos.active.count == 0 + end + end class NullContext diff --git a/db/migrate/20130227205845_add_state_to_context.rb b/db/migrate/20130227205845_add_state_to_context.rb new file mode 100644 index 00000000..8e0d59ff --- /dev/null +++ b/db/migrate/20130227205845_add_state_to_context.rb @@ -0,0 +1,22 @@ +class AddStateToContext < ActiveRecord::Migration + + class Context < ActiveRecord::Base + end + + def up + add_column :contexts, :state, :string, :limit => 20, :null => false + Context.reset_column_information + Context.all.each do |c| + c.state = c.hide ? 'hidden' : 'active' + c.save! + end + remove_column :contexts, :hide + end + + def down + add_column :contexts, :hide, :boolean, :default => false + Context.reset_column_information + Context.all.each { |c| c.hide = ( c.state == 'hidden' ) } + remove_column :contexts, :state + end +end diff --git a/test/fixtures/contexts.yml b/test/fixtures/contexts.yml index 49ce9d2f..15bfd1d3 100644 --- a/test/fixtures/contexts.yml +++ b/test/fixtures/contexts.yml @@ -10,7 +10,7 @@ agenda: id: 1 name: agenda position: 1 - hide: false + state: active user_id: 1 created_at: <%= today %> updated_at: <%= today %> @@ -19,7 +19,7 @@ call: id: 2 name: call position: 2 - hide: false + state: active user_id: 1 created_at: <%= today %> updated_at: <%= today %> @@ -28,7 +28,7 @@ email: id: 3 name: email position: 3 - hide: false + state: active user_id: 1 created_at: <%= today %> updated_at: <%= today %> @@ -37,7 +37,7 @@ errand: id: 4 name: errand position: 4 - hide: false + state: active user_id: 1 created_at: <%= today %> updated_at: <%= today %> @@ -46,7 +46,7 @@ lab: id: 5 name: lab position: 5 - hide: false + state: active user_id: 1 created_at: <%= today %> updated_at: <%= today %> @@ -55,7 +55,7 @@ library: id: 6 name: library position: 6 - hide: false + state: active user_id: 1 created_at: <%= today %> updated_at: <%= today %> @@ -64,7 +64,7 @@ freetime: id: 7 name: freetime position: 7 - hide: false + state: active user_id: 1 created_at: <%= today %> updated_at: <%= today %> @@ -73,7 +73,7 @@ office: id: 8 name: office position: 8 - hide: false + state: active user_id: 1 created_at: <%= today %> updated_at: <%= today %> @@ -82,7 +82,7 @@ waitingfor: id: 9 name: waiting for position: 9 - hide: false + state: active user_id: 1 created_at: <%= today %> updated_at: <%= today %> @@ -91,7 +91,7 @@ office_otheruser: id: 10 name: office position: 1 - hide: false + state: active user_id: 2 created_at: <%= today %> updated_at: <%= today %> @@ -100,7 +100,7 @@ waitingfor_otheruser: id: 11 name: waiting for position: 2 - hide: false + state: active user_id: 2 created_at: <%= today %> updated_at: <%= today %> @@ -109,7 +109,7 @@ someday_maybe: id: 12 name: someday maybe position: 10 - hide: true + state: hidden user_id: 1 created_at: <%= today %> updated_at: <%= today %> @@ -118,7 +118,7 @@ inbox: id: 13 name: Inbox position: 1 - hide: false + state: active user_id: 4 created_at: <%= today %> updated_at: <%= today %> @@ -127,7 +127,7 @@ anothercontext: id: 14 name: anothercontext position: 2 - hide: false + state: active user_id: 4 created_at: <%= today %> updated_at: <%= today %> diff --git a/test/unit/context_test.rb b/test/unit/context_test.rb index da7e14fe..b3b56196 100644 --- a/test/unit/context_test.rb +++ b/test/unit/context_test.rb @@ -54,14 +54,6 @@ class ContextTest < ActiveSupport::TestCase assert_equal @agenda.name, @agenda.title end - def test_hidden_attr_reader - assert !@agenda.hidden? - @agenda.hide = true - @agenda.save! - @agenda.reload - assert_equal true, @agenda.hidden? - end - def test_null_object c = Context.null_object assert c.nil? @@ -75,4 +67,34 @@ class ContextTest < ActiveSupport::TestCase assert c.new_record_before_save?, "newly created record should be new_record" end + def test_hide_context + assert @agenda.active? + @agenda.hide! + assert @agenda.hidden? + end + + def test_closing_context_guarded_for_active_todos + assert @agenda.active? + assert AASM::InvalidTransition do + @agenda.close! + end + + @agenda.todos.active.each {|t| t.complete! } + @agenda.close! + assert @agenda.closed? + end + + def test_activating_closed_context + # given a context @agenda that is closed + @agenda.todos.active.each {|t| t.complete! } + @agenda.close! + assert @agenda.closed? + + # when I activate @agenda + @agenda.activate! + + # then @agenda should have an active state + assert @agenda.active? + end + end