From f782e0f4d4f7cb6073bdfb85bcd663488adec56d Mon Sep 17 00:00:00 2001
From: Eric Allen
Date: Tue, 27 Apr 2010 10:18:07 -0400
Subject: [PATCH 01/64] Activate deferred todos before initting @todos
---
app/controllers/todos_controller.rb | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/app/controllers/todos_controller.rb b/app/controllers/todos_controller.rb
index 4ad8446e..7d203e59 100644
--- a/app/controllers/todos_controller.rb
+++ b/app/controllers/todos_controller.rb
@@ -4,6 +4,7 @@ class TodosController < ApplicationController
skip_before_filter :login_required, :only => [:index, :calendar]
prepend_before_filter :login_or_feed_token_required, :only => [:index, :calendar]
+ append_before_filter :find_and_activate_ready, :only => [:index, :list_deferred]
append_before_filter :init, :except => [ :destroy, :completed,
:completed_archive, :check_deferred, :toggle_check, :toggle_star,
:edit, :update, :create, :calendar, :auto_complete_for_predecessor, :remove_predecessor, :add_predecessor]
@@ -11,7 +12,6 @@ class TodosController < ApplicationController
protect_from_forgery :except => [:auto_complete_for_predecessor]
def index
- current_user.deferred_todos.find_and_activate_ready
@projects = current_user.projects.find(:all, :include => [:default_context])
@contexts = current_user.contexts.find(:all)
@@ -438,7 +438,6 @@ class TodosController < ApplicationController
@projects = current_user.projects.find(:all, :include => [ :todos, :default_context ])
@contexts_to_show = @contexts = current_user.contexts.find(:all, :include => [ :todos ])
- current_user.deferred_todos.find_and_activate_ready
@not_done_todos = current_user.deferred_todos + current_user.pending_todos
@count = @not_done_todos.size
@down_count = @count
@@ -652,11 +651,15 @@ class TodosController < ApplicationController
def get_todo_from_params
@todo = current_user.todos.find(params['id'])
end
+
+ def find_and_activate_ready
+ current_user.deferred_todos.find_and_activate_ready
+ end
def init
@source_view = params['_source_view'] || 'todo'
init_data_for_sidebar unless mobile?
- init_todos
+ init_todos
end
def with_feed_query_scope(&block)
From e1a92ced7c16119fc89fceccd3c46d9d3e0d45fc Mon Sep 17 00:00:00 2001
From: Eric Allen
Date: Tue, 27 Apr 2010 11:03:50 -0400
Subject: [PATCH 02/64] Don't substitute lt and gt symbols
Closes #824 (hopefully once and for all?)
---
app/models/todo.rb | 4 ----
1 file changed, 4 deletions(-)
diff --git a/app/models/todo.rb b/app/models/todo.rb
index 7fd64628..8d5cfada 100644
--- a/app/models/todo.rb
+++ b/app/models/todo.rb
@@ -287,10 +287,6 @@ class Todo < ActiveRecord::Base
return successors.find_all {|t| t.active? or t.deferred?}
end
- def notes=(value)
- super(value.try(:gsub, /, '<').try(:gsub, />/, '>'))
- end
-
def raw_notes=(value)
self[:notes] = value
end
From 23977f3f0e3eaf48eb4eaa7f817d8f9164cd7a24 Mon Sep 17 00:00:00 2001
From: Eric Allen
Date: Tue, 27 Apr 2010 11:07:28 -0400
Subject: [PATCH 03/64] Don't include completed projects in autocomplete
Closes #1026
---
app/controllers/projects_controller.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 2364ea97..9a3b8242 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -26,7 +26,7 @@ class ProjectsController < ApplicationController
format.rss &render_rss_feed
format.atom &render_atom_feed
format.text &render_text_feed
- format.autocomplete { render :text => for_autocomplete(@projects, params[:q]) }
+ format.autocomplete { render :text => for_autocomplete(@projects.reject(&:completed?), params[:q]) }
end
end
end
From 0c161be46664858feac1ff362738712eb865a811 Mon Sep 17 00:00:00 2001
From: Eric Allen
Date: Tue, 27 Apr 2010 11:16:56 -0400
Subject: [PATCH 04/64] Fix recurring todo autocompleteion
* Enable rich interaction on edit (to trigger autocompleter)
* Don't try to reset autocomplete lists, since they come from the server now
Fixes #1022
---
app/views/recurring_todos/edit.js.rjs | 1 +
app/views/recurring_todos/update.js.rjs | 6 +-----
2 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/app/views/recurring_todos/edit.js.rjs b/app/views/recurring_todos/edit.js.rjs
index 9b4706b1..2345f9b6 100644
--- a/app/views/recurring_todos/edit.js.rjs
+++ b/app/views/recurring_todos/edit.js.rjs
@@ -2,3 +2,4 @@ page << "TracksForm.toggle_overlay();"
page['new-recurring-todo'].hide
page['edit-recurring-todo'].replace_html :partial => 'recurring_todos/edit_form'
page['edit-recurring-todo'].show
+page << "enable_rich_interaction();"
diff --git a/app/views/recurring_todos/update.js.rjs b/app/views/recurring_todos/update.js.rjs
index ad35f1ef..626ba168 100644
--- a/app/views/recurring_todos/update.js.rjs
+++ b/app/views/recurring_todos/update.js.rjs
@@ -8,10 +8,6 @@ if @saved
status_message = 'Added new context / ' + status_message if @new_context_created
page.notify :notice, status_message, 5.0
- # update auto completer arrays for context and project
- page << "contextAutoCompleter.options.array = #{context_names_for_autocomplete}; contextAutoCompleter.changed = true" if @new_context_created
- page << "projectAutoCompleter.options.array = #{project_names_for_autocomplete}; projectAutoCompleter.changed = true" if @new_project_created
-
# replace old recurring todo with updated todo
page.replace dom_id(@recurring_todo), :partial => 'recurring_todos/recurring_todo', :locals => { :recurring_todo => @recurring_todo }
page.visual_effect :highlight, dom_id(@recurring_todo), :duration => 3
@@ -19,4 +15,4 @@ if @saved
else
page.show 'edit_status'
page.replace_html 'edit_status', "#{error_messages_for('recurring_todo')}"
-end
\ No newline at end of file
+end
From 9d5503a91e638664c0412389e771b6e34c8cf52b Mon Sep 17 00:00:00 2001
From: Reinier Balt
Date: Sat, 1 May 2010 17:19:28 +0200
Subject: [PATCH 05/64] fix #997. The chart with the visible actions now
excludes pending actions. Also some cleanupt to use named_scope
---
app/controllers/stats_controller.rb | 3 ++-
app/models/todo.rb | 3 +++
app/views/stats/_totals.rhtml | 22 ++++++++++++----------
3 files changed, 17 insertions(+), 11 deletions(-)
diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb
index 3847c47a..004b335c 100755
--- a/app/controllers/stats_controller.rb
+++ b/app/controllers/stats_controller.rb
@@ -319,6 +319,7 @@ class StatsController < ApplicationController
# - actions not part of a hidden project
# - actions not part of a hidden context
# - actions not deferred (show_from must be null)
+ # - actions not pending/blocked
@actions_running_time = @actions.find_by_sql([
"SELECT t.created_at "+
@@ -326,7 +327,7 @@ class StatsController < ApplicationController
"WHERE t.user_id=? "+
"AND t.completed_at IS NULL " +
"AND t.show_from IS NULL " +
- "AND NOT (p.state='hidden' OR c.hide=?) " +
+ "AND NOT (p.state='hidden' OR p.state='pending' OR c.hide=?) " +
"ORDER BY t.created_at ASC", @user.id, true]
)
diff --git a/app/models/todo.rb b/app/models/todo.rb
index 7fd64628..e4c60712 100644
--- a/app/models/todo.rb
+++ b/app/models/todo.rb
@@ -18,7 +18,10 @@ class Todo < ActiveRecord::Base
named_scope :active, :conditions => { :state => 'active' }
named_scope :not_completed, :conditions => ['NOT (todos.state = ? )', 'completed']
+ named_scope :completed, :conditions => ["NOT completed_at IS NULL"]
named_scope :are_due, :conditions => ['NOT (todos.due IS NULL)']
+ named_scope :deferred, :conditions => ["completed_at IS NULL AND NOT show_from IS NULL"]
+ named_scope :blocked, :conditions => ['todos.state = ?', 'pending']
STARRED_TAG_NAME = "starred"
RE_TODO = /[^"]+/
diff --git a/app/views/stats/_totals.rhtml b/app/views/stats/_totals.rhtml
index 02e2301d..500fde10 100755
--- a/app/views/stats/_totals.rhtml
+++ b/app/views/stats/_totals.rhtml
@@ -1,19 +1,21 @@
You have <%= @projects.count%> projects.
- Of those <%= @projects.count(:conditions => "state = 'active'")%> are active projects,
- <%= @projects.count(:conditions => "state = 'hidden'")%> hidden projects and
-<%= @projects.count(:conditions => "state = 'completed'")%> completed projects
+ Of those <%= @projects.active.count%> are active projects,
+ <%= @projects.hidden.count%> hidden projects and
+<%= @projects.completed.count%> completed projects
You have <%= @contexts.count%> contexts.
-Of those <%= @contexts.count(:conditions => ["hide = ?", false])%> are visible contexts and
-<%= @contexts.count(:conditions => ["hide = ?", true]) %> are hidden contexts
+Of those <%= @contexts.active.count%> are visible contexts and
+<%= @contexts.hidden.count%> are hidden contexts
<% unless @actions.empty? -%>
-
You have <%= @actions.count(:conditions => "completed_at IS NULL") %> incomplete actions
-of which <%= @actions.count(:conditions => "completed_at IS NULL AND NOT show_from IS NULL") %> are deferred actions.
+
Since your first action on <%= format_date(@first_action.created_at) %>
+you have a total of <%= @actions.count %> actions.
+<%= @actions.completed.count %> of these are completed.
-
Since your first action on <%= format_date(@first_action.created_at) %>
-you have a total of <%= @actions.count %> actions.
-<%= @actions.count(:conditions => "NOT completed_at IS NULL") %> of these are completed.
+
You have <%= @actions.not_completed.count %> incomplete actions
+of which <%= @actions.deferred.count %> are deferred actions
+in the tickler and <%= @actions.blocked.count %> are dependent on the completion of other actions.
+.
You have <%= @tags_count-%> tags placed on actions. Of those tags,
<%= @unique_tags_count -%> are unique.
From fabc15e061ed34f0da6ba48802e391c4bb2775bd Mon Sep 17 00:00:00 2001
From: Reinier Balt
Date: Sat, 1 May 2010 17:32:55 +0200
Subject: [PATCH 06/64] fix #987 where feeds_path returned the mobile url and
not the non-mobile one.
---
config/routes.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/config/routes.rb b/config/routes.rb
index 7bc7b533..4035cbf0 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -58,8 +58,8 @@ ActionController::Routing::Routes.draw do |map|
map.root :controller => 'todos' # Make OpenID happy because it needs #root_url defined
map.resources :notes
- map.feeds 'feeds', :controller => 'feedlist', :action => 'index'
map.feeds 'feeds.m', :controller => 'feedlist', :action => 'index', :format => 'm'
+ map.feeds 'feeds', :controller => 'feedlist', :action => 'index'
if Rails.env == 'test'
map.connect '/selenium_helper/login', :controller => 'selenium_helper', :action => 'login'
From 8bc3a484b270b8d0024e5940ab8c26c9a74086c9 Mon Sep 17 00:00:00 2001
From: Reinier Balt
Date: Sun, 2 May 2010 16:41:45 +0200
Subject: [PATCH 07/64] fix 1018. Added validations for the recurring target of
recurring todos
---
app/models/recurring_todo.rb | 30 ++++++++++++++++++++++--------
1 file changed, 22 insertions(+), 8 deletions(-)
diff --git a/app/models/recurring_todo.rb b/app/models/recurring_todo.rb
index 86c549f1..9a159c4c 100644
--- a/app/models/recurring_todo.rb
+++ b/app/models/recurring_todo.rb
@@ -29,13 +29,17 @@ class RecurringTodo < ActiveRecord::Base
validates_presence_of :description
validates_presence_of :recurring_period
+ validates_presence_of :target
+ validates_presence_of :recurring_period
+ validates_presence_of :ends_on
+ validates_presence_of :context
+
validates_length_of :description, :maximum => 100
validates_length_of :notes, :maximum => 60000, :allow_nil => true
- validates_presence_of :context
-
validate :period_specific_validations
validate :starts_and_ends_on_validations
+ validate :set_recurrence_on_validations
def period_specific_validations
periods = %W[daily weekly monthly yearly]
@@ -59,7 +63,6 @@ class RecurringTodo < ActiveRecord::Base
something_set = false
%w{sunday monday tuesday wednesday thursday friday}.each do |day|
something_set ||= self.send("on_#{day}")
-
end
errors.add_to_base("You must specify at least one day on which the todo recurs") if !something_set
end
@@ -104,6 +107,21 @@ class RecurringTodo < ActiveRecord::Base
errors.add_to_base("The end of the recurrence is not selected") unless ends_on == "no_end_date"
end
end
+
+ def set_recurrence_on_validations
+ # show always or x days before due date. x not null
+ case self.target
+ when 'show_from_date'
+ # no validations
+ when 'due_date'
+ errors.add_to_base("Please select when to show the action") if show_always.nil?
+ unless show_always
+ errors.add_to_base("Please fill in the number of days to show the todo before the due date") if show_from_delta.nil? || show_from_delta.blank?
+ end
+ else
+ raise Exception.new, "unexpected value of recurrence target selector '#{self.recurrence_target}'"
+ end
+ end
# the following recurrence patterns can be stored:
#
@@ -726,11 +744,7 @@ class RecurringTodo < ActiveRecord::Base
end
protected
-
- def validate
- errors.add("", "At least one day must be selected in the weekly pattern") if self.every_day == ' '
- end
-
+
def determine_start(previous)
if previous.nil?
start = self.start_from.nil? ? Time.zone.now : self.start_from
From 5c25e4569e6660bd2a2a1e12e7e1bb9367e849d8 Mon Sep 17 00:00:00 2001
From: Reinier Balt
Date: Sun, 2 May 2010 18:16:29 +0200
Subject: [PATCH 08/64] fix #1002. every nth week was off by one week for
recurring weekly todos. Thanks Thomas for spotting this.
Updated the wrong test too.
---
app/models/recurring_todo.rb | 12 +++++-------
test/fixtures/recurring_todos.yml | 2 +-
test/unit/recurring_todo_test.rb | 8 +++++++-
3 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/app/models/recurring_todo.rb b/app/models/recurring_todo.rb
index 9a159c4c..2f6d623b 100644
--- a/app/models/recurring_todo.rb
+++ b/app/models/recurring_todo.rb
@@ -61,7 +61,7 @@ class RecurringTodo < ActiveRecord::Base
errors.add_to_base("Every other nth week may not be empty for recurrence setting")
end
something_set = false
- %w{sunday monday tuesday wednesday thursday friday}.each do |day|
+ %w{sunday monday tuesday wednesday thursday friday saturday}.each do |day|
something_set ||= self.send("on_#{day}")
end
errors.add_to_base("You must specify at least one day on which the todo recurs") if !something_set
@@ -406,9 +406,9 @@ class RecurringTodo < ActiveRecord::Base
end
def recurrence_pattern
+ return "invalid repeat pattern" if every_other1.nil?
case recurring_period
when 'daily'
- return "invalid repeat pattern" if every_other1.nil?
if only_work_days
return "on work days"
else
@@ -419,21 +419,19 @@ class RecurringTodo < ActiveRecord::Base
end
end
when 'weekly'
- return "invalid repeat pattern" if every_other1.nil?
if every_other1 > 1
return "every #{every_other1} weeks"
else
return 'weekly'
end
when 'monthly'
- return "invalid repeat pattern" if every_other1.nil? || every_other2.nil?
+ return "invalid repeat pattern" if every_other2.nil?
if self.recurrence_selector == 0
return "every #{self.every_other2} month#{self.every_other2>1?'s':''} on day #{self.every_other1}"
else
return "every #{self.xth} #{self.day_of_week} of every #{self.every_other2} month#{self.every_other2>1?'s':''}"
end
when 'yearly'
- return "invalid repeat pattern" if every_other1.nil?
if self.recurrence_selector == 0
return "every year on #{self.month_of_year} #{self.every_other1}"
else
@@ -553,8 +551,8 @@ class RecurringTodo < ActiveRecord::Base
start = previous + 1.day
if start.wday() == 0
# we went to a new week , go to the nth next week and find first match
- # that week
- start += self.every_other1.week
+ # that week. Note that we already went into the next week, so -1
+ start += (self.every_other1-1).week
end
unless self.start_from.nil?
# check if the start_from date is later than previous. If so, use
diff --git a/test/fixtures/recurring_todos.yml b/test/fixtures/recurring_todos.yml
index daffc38c..db630d68 100644
--- a/test/fixtures/recurring_todos.yml
+++ b/test/fixtures/recurring_todos.yml
@@ -64,7 +64,7 @@ call_bill_gates_every_workday:
show_from_delta: ~
recurring_period: daily
recurrence_selector: ~
- every_other1: ~
+ every_other1: 1
every_other2: ~
every_other3: ~
every_day: ~
diff --git a/test/unit/recurring_todo_test.rb b/test/unit/recurring_todo_test.rb
index 6e4c5b0b..8ae3f6da 100644
--- a/test/unit/recurring_todo_test.rb
+++ b/test/unit/recurring_todo_test.rb
@@ -124,7 +124,9 @@ class RecurringTodoTest < ActiveSupport::TestCase
due_date = @weekly_every_day.get_due_date(@sunday)
assert_equal @monday, due_date
- # saturday is last day in week, so the next date should be sunday + n_weeks
+ # saturday is last day in week, so the next date should be sunday + n-1 weeks
+ # n-1 because sunday is already in the next week
+ @weekly_every_day.every_other1 = 3
due_date = @weekly_every_day.get_due_date(@saturday)
assert_equal @sunday + 2.weeks, due_date
@@ -141,6 +143,10 @@ class RecurringTodoTest < ActiveSupport::TestCase
assert_equal @wednesday, due_date
due_date = @weekly_every_day.get_due_date(@wednesday)
assert_equal @tuesday+1.week, due_date
+
+ @weekly_every_day.every_day = ' s'
+ due_date = @weekly_every_day.get_due_date(@sunday)
+ assert_equal @saturday+1.week, due_date
end
def test_monthly_pattern
From 0198a2fa13ab3f784fa17556e3831343cb9518d7 Mon Sep 17 00:00:00 2001
From: Reinier Balt
Date: Sun, 2 May 2010 18:25:25 +0200
Subject: [PATCH 09/64] fix #936 by adding index on state for todos. Needs
migration of database.
---
db/migrate/20100502162317_add_index_to_todo_state.rb | 9 +++++++++
1 file changed, 9 insertions(+)
create mode 100644 db/migrate/20100502162317_add_index_to_todo_state.rb
diff --git a/db/migrate/20100502162317_add_index_to_todo_state.rb b/db/migrate/20100502162317_add_index_to_todo_state.rb
new file mode 100644
index 00000000..6e3d01bf
--- /dev/null
+++ b/db/migrate/20100502162317_add_index_to_todo_state.rb
@@ -0,0 +1,9 @@
+class AddIndexToTodoState < ActiveRecord::Migration
+ def self.up
+ add_index :todos, :state
+ end
+
+ def self.down
+ remove_index :todos, :state
+ end
+end
\ No newline at end of file
From 0d7980e87b6123aa040984daecbcc0e91c0c69c9 Mon Sep 17 00:00:00 2001
From: Reinier Balt
Date: Mon, 3 May 2010 21:26:48 +0200
Subject: [PATCH 10/64] migrate selenium for users to cucumber
---
app/controllers/login_controller.rb | 2 +-
app/controllers/users_controller.rb | 2 +-
features/manage_project.feature | 2 +-
features/manage_users.feature | 31 ++++++++++++++++++
features/step_definitions/context_steps.rb | 38 +++++++++++-----------
features/step_definitions/user_steps.rb | 18 ++++++++++
features/support/paths.rb | 4 ++-
test/selenium/users/delete_user.rsel | 7 ----
8 files changed, 74 insertions(+), 30 deletions(-)
create mode 100644 features/manage_users.feature
delete mode 100644 test/selenium/users/delete_user.rsel
diff --git a/app/controllers/login_controller.rb b/app/controllers/login_controller.rb
index 0c1037ed..5106686f 100644
--- a/app/controllers/login_controller.rb
+++ b/app/controllers/login_controller.rb
@@ -54,7 +54,7 @@ class LoginController < ApplicationController
end
when :get
if User.no_users_yet?
- redirect_to :controller => 'users', :action => 'new'
+ redirect_to signup_path
return
end
end
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 387c7689..1198837f 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -90,7 +90,7 @@ class UsersController < ApplicationController
unless user.valid?
session['new_user'] = user
- redirect_to :action => 'new'
+ redirect_to signup_path
return
end
diff --git a/features/manage_project.feature b/features/manage_project.feature
index 5db9910e..74eaaeec 100644
--- a/features/manage_project.feature
+++ b/features/manage_project.feature
@@ -11,7 +11,7 @@ Feature: Manage a project
And I have logged in as "testuser" with password "secret"
And there exists a project "manage me" for user "testuser"
- @selenium
+ @selenium, @wip
Scenario: I can describe the project using markup
When I visit the "manage me" project
And I edit the project description to "_successfull outcome_: project is *done*"
diff --git a/features/manage_users.feature b/features/manage_users.feature
new file mode 100644
index 00000000..6d716853
--- /dev/null
+++ b/features/manage_users.feature
@@ -0,0 +1,31 @@
+Feature: Manage users
+
+ In order to be able to manage the users able to use Tracks
+ As the administrator of this installed Tracks
+ I want to add and delete accounts of users
+
+ Background:
+ Given the following user records
+ | login | password | is_admin |
+ | testuser | secret | false |
+ | admin | secret | true |
+ And I have logged in as "admin" with password "secret"
+
+ Scenario: Show all accounts
+ When I go to the manage users page
+ Then I should see "testuser"
+ And I should see "admin"
+
+ Scenario: Add new account
+ When I go to the manage users page
+ And I follow "Signup new user"
+ Then I should be on the signup page
+ When I submit the signup form with username "new.user", password "secret123" and confirm with "secret123"
+ Then I should be on the manage users page
+ And I should see "new.user"
+
+ @selenium
+ Scenario: Delete account from users page
+ When I go to the manage users page
+ And I delete the user "testuser"
+ Then I should see that a user named "testuser" is not present
diff --git a/features/step_definitions/context_steps.rb b/features/step_definitions/context_steps.rb
index 9bab68a5..fa117871 100644
--- a/features/step_definitions/context_steps.rb
+++ b/features/step_definitions/context_steps.rb
@@ -2,6 +2,13 @@ Given /^I have a context called "([^\"]*)"$/ do |context_name|
@context = @current_user.contexts.create!(:name => context_name)
end
+Given /^I have a context "([^\"]*)" with (.*) actions$/ do |context_name, number_of_actions|
+ context = @current_user.contexts.create!(:name => context_name)
+ 1.upto number_of_actions.to_i do |i|
+ @current_user.todos.create!(:context_id => context.id, :description => "todo #{i}")
+ end
+end
+
When /^I visits the context page for "([^\"]*)"$/ do |context_name|
context = @current_user.contexts.find_by_name(context_name)
context.should_not be_nil
@@ -14,25 +21,6 @@ When /^I edit the context name in place to be "([^\"]*)"$/ do |new_context_name|
click_button "OK"
end
-Then /^I should see the context name is "([^\"]*)"$/ do |context_name|
- Then "I should see \"#{context_name}\""
-end
-
-Then /^he should see that a context named "([^\"]*)" is present$/ do |context_name|
- Then "I should see \"#{context_name}\""
-end
-
-Then /^he should see that a context named "([^\"]*)" is not present$/ do |context_name|
- Then "I should not see \"#{context_name} (\""
-end
-
-Given /^I have a context "([^\"]*)" with (.*) actions$/ do |context_name, number_of_actions|
- context = @current_user.contexts.create!(:name => context_name)
- 1.upto number_of_actions.to_i do |i|
- @current_user.todos.create!(:context_id => context.id, :description => "todo #{i}")
- end
-end
-
When /^I delete the context "([^\"]*)"$/ do |context_name|
context = @current_user.contexts.find_by_name(context_name)
context.should_not be_nil
@@ -51,3 +39,15 @@ When /^I edit the context to rename it to "([^\"]*)"$/ do |new_name|
selenium.is_visible("flash")
end
end
+
+Then /^I should see the context name is "([^\"]*)"$/ do |context_name|
+ Then "I should see \"#{context_name}\""
+end
+
+Then /^he should see that a context named "([^\"]*)" is present$/ do |context_name|
+ Then "I should see \"#{context_name}\""
+end
+
+Then /^he should see that a context named "([^\"]*)" is not present$/ do |context_name|
+ Then "I should not see \"#{context_name} (\""
+end
\ No newline at end of file
diff --git a/features/step_definitions/user_steps.rb b/features/step_definitions/user_steps.rb
index 834bd20f..05022302 100644
--- a/features/step_definitions/user_steps.rb
+++ b/features/step_definitions/user_steps.rb
@@ -10,6 +10,24 @@ Given "no users exists" do
User.delete_all
end
+When /^I delete the user "([^\"]*)"$/ do |username|
+ # click "//tr[@id='user-3']//img"
+ # assert_confirmation "Warning: this will delete user 'john', all their actions, contexts, project and notes. Are you sure that you want to continue?"
+ user = User.find_by_login(username)
+ user.should_not be_nil
+
+ selenium.click "xpath=//tr[@id='user-#{user.id}']//img"
+ selenium.get_confirmation.should == "Warning: this will delete user '#{user.login}', all their actions, contexts, project and notes. Are you sure that you want to continue?"
+ wait_for do
+ !selenium.is_element_present("//tr[@id='user-#{user.id}']//img")
+ end
+
+end
+
+Then /^I should see that a user named "([^\"]*)" is not present$/ do |username|
+ Then "I should not see \"#{username} (\""
+end
+
Then "I should be an admin" do
# just check on the presence of the menu item for managing users
Then "I should see \"Manage users\""
diff --git a/features/support/paths.rb b/features/support/paths.rb
index 91222396..cb895557 100644
--- a/features/support/paths.rb
+++ b/features/support/paths.rb
@@ -9,13 +9,15 @@ module NavigationHelpers
when /the statistics page/
stats_path
when /the signup page/
- "/users/new"
+ signup_path
when /the login page/
login_path
when /the notes page/
notes_path
when /the contexts page/
contexts_path
+ when /the manage users page/
+ users_path
# Add more page name => path mappings here
diff --git a/test/selenium/users/delete_user.rsel b/test/selenium/users/delete_user.rsel
deleted file mode 100644
index 32ff3545..00000000
--- a/test/selenium/users/delete_user.rsel
+++ /dev/null
@@ -1,7 +0,0 @@
-setup :fixtures => :all
-login :as => 'admin'
-open '/users'
-assert_text_present "John Deere"
-click "//tr[@id='user-3']//img"
-assert_confirmation "Warning: this will delete user 'john', all their actions, contexts, project and notes. Are you sure that you want to continue?"
-wait_for_text_not_present "John Deere"
\ No newline at end of file
From e1b52aeb13b11d0b4cb5905eee7fbf63789ecae8 Mon Sep 17 00:00:00 2001
From: Reinier Balt
Date: Wed, 5 May 2010 13:00:44 +0200
Subject: [PATCH 11/64] replace selenium script with cucumber story for
switching recurrence option
---
features/recurring_todos.feature | 25 +++++++++++++++++++
.../step_definitions/recurring_todo_steps.rb | 7 ++++++
features/support/paths.rb | 2 ++
.../switch_recurrence_options.rsel | 12 ---------
4 files changed, 34 insertions(+), 12 deletions(-)
create mode 100644 features/recurring_todos.feature
create mode 100644 features/step_definitions/recurring_todo_steps.rb
delete mode 100644 test/selenium/recurring_todos/switch_recurrence_options.rsel
diff --git a/features/recurring_todos.feature b/features/recurring_todos.feature
new file mode 100644
index 00000000..98d54c82
--- /dev/null
+++ b/features/recurring_todos.feature
@@ -0,0 +1,25 @@
+Feature: Manage recurring todos
+
+ In order to manage repeating todos
+ As a Tracks user
+ I want to view, edit, add, or remove recurrence patterns of repeating todos
+
+ Background:
+ Given the following user record
+ | login | password | is_admin |
+ | testuser | secret | false |
+ And I have logged in as "testuser" with password "secret"
+
+ @selenium
+ Scenario: Being able to select daily, weekly, monthly and yearly pattern
+ When I go to the repeating todos page
+ And I follow "Add a new recurring action"
+ Then I should see the form for "Daily" recurrence pattern
+ When I select "Weekly" recurrence pattern
+ Then I should see the form for "Weekly" recurrence pattern
+ When I select "Monthly" recurrence pattern
+ Then I should see the form for "Monthly" recurrence pattern
+ When I select "Yearly" recurrence pattern
+ Then I should see the form for "Yearly" recurrence pattern
+ When I select "Daily" recurrence pattern
+ Then I should see the form for "Daily" recurrence pattern
\ No newline at end of file
diff --git a/features/step_definitions/recurring_todo_steps.rb b/features/step_definitions/recurring_todo_steps.rb
new file mode 100644
index 00000000..2982eb26
--- /dev/null
+++ b/features/step_definitions/recurring_todo_steps.rb
@@ -0,0 +1,7 @@
+When /^I select "([^\"]*)" recurrence pattern$/ do |recurrence_period|
+ selenium.click("recurring_todo_recurring_period_#{recurrence_period.downcase}")
+end
+
+Then /^I should see the form for "([^\"]*)" recurrence pattern$/ do |recurrence_period|
+ selenium.is_visible("recurring_#{recurrence_period.downcase}")
+end
diff --git a/features/support/paths.rb b/features/support/paths.rb
index cb895557..51edcca2 100644
--- a/features/support/paths.rb
+++ b/features/support/paths.rb
@@ -18,6 +18,8 @@ module NavigationHelpers
contexts_path
when /the manage users page/
users_path
+ when /the repeating todos page/
+ recurring_todos_path
# Add more page name => path mappings here
diff --git a/test/selenium/recurring_todos/switch_recurrence_options.rsel b/test/selenium/recurring_todos/switch_recurrence_options.rsel
deleted file mode 100644
index 073c0f9c..00000000
--- a/test/selenium/recurring_todos/switch_recurrence_options.rsel
+++ /dev/null
@@ -1,12 +0,0 @@
-setup :fixtures => :users, :clear_tables => [:projects, :contexts, :todos]
-login :as => 'admin'
-open "/recurring_todos"
-click "css=#recurring_new_container a"
-click "recurring_todo_recurring_period_daily"
-assert_visible "recurring_daily"
-click "recurring_todo_recurring_period_weekly"
-assert_visible "recurring_weekly"
-click "recurring_todo_recurring_period_monthly"
-assert_visible "recurring_monthly"
-click "recurring_todo_recurring_period_yearly"
-assert_visible "recurring_yearly"
From f53b386bd1d0a58237c220fcb712c7863bec8a2b Mon Sep 17 00:00:00 2001
From: Reinier Balt
Date: Wed, 5 May 2010 13:15:00 +0200
Subject: [PATCH 12/64] remove anoying message about login text not found when
running cucumber/selenium
---
features/step_definitions/login_steps.rb | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/features/step_definitions/login_steps.rb b/features/step_definitions/login_steps.rb
index b4d80868..b6f52cfa 100644
--- a/features/step_definitions/login_steps.rb
+++ b/features/step_definitions/login_steps.rb
@@ -3,6 +3,10 @@ Given /^I have logged in as "(.*)" with password "(.*)"$/ do |username, password
fill_in "Login", :with => username
fill_in "Password", :with => password
click_button
+ selenium.wait_for_page_to_load(5000)
+# wait_for do
+# selenium.is_visible("flash")
+# end
response.should contain(/Login successful/)
@current_user = User.find_by_login(username)
end
From a0b642dab349dd2a61e813a23a862e904df03911 Mon Sep 17 00:00:00 2001
From: Reinier Balt
Date: Wed, 5 May 2010 13:16:54 +0200
Subject: [PATCH 13/64] remove commented lines from last commit
---
features/step_definitions/login_steps.rb | 3 ---
1 file changed, 3 deletions(-)
diff --git a/features/step_definitions/login_steps.rb b/features/step_definitions/login_steps.rb
index b6f52cfa..e3db63fd 100644
--- a/features/step_definitions/login_steps.rb
+++ b/features/step_definitions/login_steps.rb
@@ -4,9 +4,6 @@ Given /^I have logged in as "(.*)" with password "(.*)"$/ do |username, password
fill_in "Password", :with => password
click_button
selenium.wait_for_page_to_load(5000)
-# wait_for do
-# selenium.is_visible("flash")
-# end
response.should contain(/Login successful/)
@current_user = User.find_by_login(username)
end
From eef1b6b7a9b148fa253288e2a832125a95af378b Mon Sep 17 00:00:00 2001
From: Reinier Balt
Date: Wed, 5 May 2010 13:19:26 +0200
Subject: [PATCH 14/64] remove selenium scripts that were already converted to
cucumber
---
.../context_listing/edit_then_delete.rsel | 15 ---------------
test/selenium/context_listing/edit_twice.rsel | 19 -------------------
2 files changed, 34 deletions(-)
delete mode 100644 test/selenium/context_listing/edit_then_delete.rsel
delete mode 100644 test/selenium/context_listing/edit_twice.rsel
diff --git a/test/selenium/context_listing/edit_then_delete.rsel b/test/selenium/context_listing/edit_then_delete.rsel
deleted file mode 100644
index 4f35a28b..00000000
--- a/test/selenium/context_listing/edit_then_delete.rsel
+++ /dev/null
@@ -1,15 +0,0 @@
-setup :fixtures => :all
-login :as => 'admin'
-open "/contexts"
-click "css=#context_3 .buttons img.edit_item"
-wait_for_visible "edit_context_3"
-wait_for_not_visible "context_3"
-type "//div[@id='edit_context_3'] //input[@name='context[name]']", "telegraph"
-click "//div[@id='edit_context_3'] //button"
-wait_for_not_visible "edit_context_3"
-wait_for_visible "context_3"
-click "css=#context_3 .buttons img.delete_item"
-assert_confirmation "Are you sure that you want to delete the context 'telegraph'?"
-wait_for_visible "flash"
-wait_for_text "flash", "Deleted context 'telegraph'"
-wait_for_element_not_present "context_3"
\ No newline at end of file
diff --git a/test/selenium/context_listing/edit_twice.rsel b/test/selenium/context_listing/edit_twice.rsel
deleted file mode 100644
index 635a70d3..00000000
--- a/test/selenium/context_listing/edit_twice.rsel
+++ /dev/null
@@ -1,19 +0,0 @@
-setup :fixtures => :all
-login :as => 'admin'
-open "/contexts"
-click "css=#context_3 .buttons img.edit_item"
-wait_for_visible "edit_context_3"
-wait_for_not_visible "context_3"
-type "//div[@id='edit_context_3'] //input[@name='context[name]']", "telegraph"
-click "//div[@id='edit_context_3'] //button"
-wait_for_not_visible "edit_context_3"
-wait_for_visible "context_3"
-assert_text 'css=#context_3 .data a', 'telegraph'
-click "css=#context_3 .buttons img.edit_item"
-wait_for_visible "edit_context_3"
-wait_for_not_visible "context_3"
-type "//div[@id='edit_context_3'] //input[@name='context[name]']", "email"
-click "//div[@id='edit_context_3'] //button"
-wait_for_not_visible "edit_context_3"
-wait_for_visible "context_3"
-assert_text 'css=#context_3 .data a', 'email'
\ No newline at end of file
From 44c61d942a3ca6bae36dea989a563b6034af9ba7 Mon Sep 17 00:00:00 2001
From: Reinier Balt
Date: Wed, 5 May 2010 19:08:41 +0200
Subject: [PATCH 15/64] make sure login works for non-selenium cucumber
regression since my last commit
---
features/step_definitions/login_steps.rb | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/features/step_definitions/login_steps.rb b/features/step_definitions/login_steps.rb
index e3db63fd..49995c1d 100644
--- a/features/step_definitions/login_steps.rb
+++ b/features/step_definitions/login_steps.rb
@@ -3,7 +3,9 @@ Given /^I have logged in as "(.*)" with password "(.*)"$/ do |username, password
fill_in "Login", :with => username
fill_in "Password", :with => password
click_button
- selenium.wait_for_page_to_load(5000)
+ if response.respond_to? :selenium
+ selenium.wait_for_page_to_load(5000)
+ end
response.should contain(/Login successful/)
@current_user = User.find_by_login(username)
end
From d6e20a76c2d398fd32e580d9d5e215bd5c1e7f0c Mon Sep 17 00:00:00 2001
From: Reinier Balt
Date: Wed, 5 May 2010 19:09:51 +0200
Subject: [PATCH 16/64] migrate selenium script for integrations page and
enhance the story
---
features/show_integration_options.feature | 38 +++++++++++++++++++
features/step_definitions/context_steps.rb | 11 ++++++
.../step_definitions/integration_steps.rb | 23 +++++++++++
features/step_definitions/note_steps.rb | 1 -
features/support/paths.rb | 2 +
.../no_script_if_no_contexts.rsel | 14 -------
6 files changed, 74 insertions(+), 15 deletions(-)
create mode 100644 features/show_integration_options.feature
create mode 100644 features/step_definitions/integration_steps.rb
delete mode 100644 test/selenium/integrations/no_script_if_no_contexts.rsel
diff --git a/features/show_integration_options.feature b/features/show_integration_options.feature
new file mode 100644
index 00000000..c77b5562
--- /dev/null
+++ b/features/show_integration_options.feature
@@ -0,0 +1,38 @@
+Feature: Integrate Tracks in various ways
+
+ In order to use tracks with other software
+ As a Tracks user
+ I want to be informed about the various ways to integrate tracks
+
+ Background:
+ Given the following user record
+ | login | password | is_admin |
+ | testuser | secret | false |
+ And I have logged in as "testuser" with password "secret"
+
+ Scenario: I cannot see scripts when I do not have a context
+ Given I have no contexts
+ When I go to the integrations page
+ Then I should see a message that you need a context to see scripts
+
+ Scenario: I can see scripts when I have one or more contexts
+ Given I have a context called "@pc"
+ When I go to the integrations page
+ Then I should see scripts
+
+ @selenium
+ Scenario: When I select a different context the example scripts should change accoordingly
+ Given I have the following contexts:
+ | context |
+ | @pc |
+ | @home |
+ | @shops |
+ | @boss |
+ When I go to the integrations page
+ Then I should see a script "applescript1" for "@pc"
+ When I select "@home" from "applescript1-contexts"
+ Then I should see a script "applescript1" for "@home"
+ When I select "@shops" from "applescript2-contexts"
+ Then I should see a script "applescript2" for "@shops"
+ When I select "@boss" from "quicksilver-contexts"
+ Then I should see a script "quicksilver" for "@boss"
diff --git a/features/step_definitions/context_steps.rb b/features/step_definitions/context_steps.rb
index fa117871..a75f780c 100644
--- a/features/step_definitions/context_steps.rb
+++ b/features/step_definitions/context_steps.rb
@@ -1,7 +1,18 @@
+Given /^I have no contexts$/ do
+ # should probably not be needed as you use this given at the start of a scenario
+ Context.delete_all
+end
+
Given /^I have a context called "([^\"]*)"$/ do |context_name|
@context = @current_user.contexts.create!(:name => context_name)
end
+Given /^I have the following contexts:$/ do |table|
+ table.hashes.each do |context|
+ Given 'I have a context called "'+context[:context]+'"'
+ end
+end
+
Given /^I have a context "([^\"]*)" with (.*) actions$/ do |context_name, number_of_actions|
context = @current_user.contexts.create!(:name => context_name)
1.upto number_of_actions.to_i do |i|
diff --git a/features/step_definitions/integration_steps.rb b/features/step_definitions/integration_steps.rb
new file mode 100644
index 00000000..10d5727d
--- /dev/null
+++ b/features/step_definitions/integration_steps.rb
@@ -0,0 +1,23 @@
+Then /^I should see a message that you need a context to see scripts$/ do
+ Then 'I should see "You do not have any context yet. The script will be available after you add your first context"'
+end
+
+Then /^I should see scripts$/ do
+ # check on a small snippet of the first applescript
+ Then 'I should see "set returnValue to call xmlrpc"'
+end
+
+Then /^I should see a script "([^\"]*)" for "([^\"]*)"$/ do |script, context_name|
+ selenium.is_visible(script)
+ context = Context.find_by_name(context_name)
+
+ # wait for the script to refresh
+ wait_for :timeout => 15 do
+ selenium.is_text_present("#{context.id} (* #{context_name} *)")
+ end
+
+ # make sure the text is found within the textarea
+ script_source = selenium.get_text("//textarea[@id='#{script}']")
+ script_source.should =~ /#{context.id} \(\* #{context_name} \*\)/
+end
+
diff --git a/features/step_definitions/note_steps.rb b/features/step_definitions/note_steps.rb
index 630f974d..fbc93eb7 100644
--- a/features/step_definitions/note_steps.rb
+++ b/features/step_definitions/note_steps.rb
@@ -62,7 +62,6 @@ Then /^the first note should disappear$/ do
end
end
-
Then /^I should see the note text$/ do
Then "I should see \"after 50 characters\""
end
diff --git a/features/support/paths.rb b/features/support/paths.rb
index 51edcca2..19142887 100644
--- a/features/support/paths.rb
+++ b/features/support/paths.rb
@@ -20,6 +20,8 @@ module NavigationHelpers
users_path
when /the repeating todos page/
recurring_todos_path
+ when /the integrations page/
+ integrations_path
# Add more page name => path mappings here
diff --git a/test/selenium/integrations/no_script_if_no_contexts.rsel b/test/selenium/integrations/no_script_if_no_contexts.rsel
deleted file mode 100644
index 4da2ea76..00000000
--- a/test/selenium/integrations/no_script_if_no_contexts.rsel
+++ /dev/null
@@ -1,14 +0,0 @@
-setup :fixtures => :users, :clear_tables => [:projects, :contexts, :todos]
-login :as => 'admin'
-open "/integrations"
-wait_for_element_present "no_context_msg"
-
-open "/contexts"
-type "context_name", "my first context"
-click "context_new_submit"
-# wait for new context to appear before navigating away from project page to
-# make sure that the changes have been saved
-wait_for_text_present 'DRAG'
-
-open "/integrations"
-wait_for_element_present "applescript1-contexts"
From fa98c0865e638d28ea69ef36fd859ffb41ac66df Mon Sep 17 00:00:00 2001
From: Eric Allen
Date: Sat, 8 May 2010 19:30:58 -0400
Subject: [PATCH 17/64] Override AASM's initial state if specified
Fixes #977
---
app/controllers/todos_controller.rb | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/app/controllers/todos_controller.rb b/app/controllers/todos_controller.rb
index 7d203e59..480744fb 100644
--- a/app/controllers/todos_controller.rb
+++ b/app/controllers/todos_controller.rb
@@ -55,7 +55,7 @@ class TodosController < ApplicationController
predecessor_list = p.predecessor_list
@todo = current_user.todos.build(p.attributes)
-
+
if p.project_specified_by_name?
project = current_user.projects.find_or_create_by_name(p.project_name)
@new_project_created = project.new_record_before_save?
@@ -70,8 +70,16 @@ class TodosController < ApplicationController
end
@todo.add_predecessor_list(predecessor_list)
+
+ # Fix for #977 because AASM overrides @state on creation
+ specified_state = @todo.state
+
@todo.update_state_from_project
@saved = @todo.save
+
+ # Fix for #977 because AASM overrides @state on creation
+ @todo.update_attribute('state', specified_state) unless specified_state == "immediate"
+
unless (@saved == false) || tag_list.blank?
@todo.tag_with(tag_list)
@todo.tags.reload
From 86d7724b75be46a0ada3301c252960002372ff31 Mon Sep 17 00:00:00 2001
From: Eric Allen
Date: Sun, 9 May 2010 18:57:56 -0400
Subject: [PATCH 18/64] Revert "Move dependency drop target into image"
We decided that the small drop target was harder to hit, and the
justifcation for the change wasn't worth it.
This reverts commit ec68e04f2723682c5d4ab1aa08dbeb49cacf15ad.
Conflicts:
app/helpers/todos_helper.rb
public/javascripts/application.js
public/stylesheets/standard.css
---
app/helpers/todos_helper.rb | 6 +-
artwork/add_successor_on.svg | 179 ----------------------------
artwork/predecessor.svg | 175 ---------------------------
public/images/add_successor_off.png | Bin 801 -> 0 bytes
public/images/add_successor_on.png | Bin 794 -> 0 bytes
public/javascripts/application.js | 4 +-
public/stylesheets/standard.css | 13 +-
7 files changed, 7 insertions(+), 370 deletions(-)
delete mode 100644 artwork/add_successor_on.svg
delete mode 100644 artwork/predecessor.svg
delete mode 100644 public/images/add_successor_off.png
delete mode 100644 public/images/add_successor_on.png
diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb
index 994fb305..b8ea341e 100644
--- a/app/helpers/todos_helper.rb
+++ b/app/helpers/todos_helper.rb
@@ -119,10 +119,8 @@ module TodosHelper
def grip_span
unless @todo.completed?
image_tag('grip.png', :width => '7', :height => '16', :border => '0',
- :title => 'Drag onto another action to make it depend on that action',
- :class => 'grip') +
- image_tag('blank.png', :width => 16, :height => 16, :border => 0,
- :title => "Drop an action to make it depend on this action", :class => 'successor_target drop_target')
+ :title => 'Drag onto another action to make it depend on that action',
+ :class => 'grip')
end
end
diff --git a/artwork/add_successor_on.svg b/artwork/add_successor_on.svg
deleted file mode 100644
index b7b3165c..00000000
--- a/artwork/add_successor_on.svg
+++ /dev/null
@@ -1,179 +0,0 @@
-
-
-
-
diff --git a/artwork/predecessor.svg b/artwork/predecessor.svg
deleted file mode 100644
index 75e1ea1a..00000000
--- a/artwork/predecessor.svg
+++ /dev/null
@@ -1,175 +0,0 @@
-
-
-
-
diff --git a/public/images/add_successor_off.png b/public/images/add_successor_off.png
deleted file mode 100644
index 183f1326da59fb9ce8dfc4de71f365f9c1e3dad6..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 801
zcmV++1K#|JP)A_TU&dEb1w4v{O4RQ_k3<{?vtzz{)F`O^mzOG
z`)>>k4BU>#BFA>^5qk^um1XlS?|jYcmjiXs;m7n5siYcEaH
z+*VcfLM#?bjE#*&L!nSO6bfCQo}PXKU=skSq9|t_$Eg!SuuLZNdVYTXk!4vK0GOSf
zeZRG}b-%T>H5v|w&qX4U#uKqzF4q}`0o%5-rfGgH6biZOAE{I-RbOBK&Fl3>6-5bh
z&RYl}@1&GAWsDJB*HJ7MA%qYB>c+>%uc@kf#qD+n7-KC52L~0-xt}pMGdVeVX<}kR
ztFbH#x~?Oe%}UcWT~f-NX__AcfqW83NQ=<
zLI~Kl4MK=ZO1V8aIC!^MEYjxY=Bs|cADnZf)9H=f-Q9-^3kz>4V+^{kqg*cI_|jw6
z*Vi|PhKBA4A!uV`Zzqt3ASzjS`MtPt|k+S#Jx-=V-iBX
zD2no8e}A6?K#gTtFbo5^Tn?Ob{K@k2@`uC2!$`b`(W1
f(&@DPuLa--f+vKa3jVpwx}gdBNaMgZL5u;Go3lJoHJ+6nX`N@YQ)ln-}Uo*
zlPB*(gb)CL#oG?Hnx4wNrl)#|&Al#GQVmy8e&sb&mtS1J_!8yd56Gsrw#xY2b$jIC
z#=~-O^#apd1=s)>;3{TO_2t=U&1ld0Dd~6TdhbUQWs!etj2aQgm$ngD>N-N&E%
zl7lDosS88J$~iNN)uH;bNU3djBs~jvek>zt$q$iOAzSX@)?&l{ne98GSt^H+X90?Msh1*A=)5X%MFb=4d}3
z-1qe1o7L+!A7PfxHGe~xl!}9XW#r84SkJAqLYSOc1#m45I3}oG_;nn3{`lU&lJy%g1;6Xg+aZ$A+aRpFFvd`MDfgQo)1+
z2pi1S@h3tE8xte^4bDm`h-E+sXX3!ZmcQi5p#PPc1TIlJ?g)EW5HU!FBYz#L5dYSI
Y?{CsPln#@-BLDyZ07*qoM6N<$f&*G*_W%F@
diff --git a/public/javascripts/application.js b/public/javascripts/application.js
index cfe11d2e..4b025f51 100644
--- a/public/javascripts/application.js
+++ b/public/javascripts/application.js
@@ -229,7 +229,7 @@ function enable_rich_interaction(){
/* Drag & Drop for successor/predecessor */
function drop_todo(evt, ui) {
dragged_todo = ui.draggable[0].id.split('_')[2];
- dropped_todo = $(this).parents('.item-show').get(0).id.split('_')[2];
+ dropped_todo = this.id.split('_')[2];
ui.draggable.remove();
$(this).block({message: null});
$.post(relative_to_root('todos/add_predecessor'),
@@ -247,7 +247,7 @@ function enable_rich_interaction(){
start: drag_todo,
stop: function() {$('.drop_target').hide();}});
- $('.successor_target').droppable({drop: drop_todo,
+ $('.item-show').droppable({drop: drop_todo,
tolerance: 'pointer',
hoverClass: 'hover'});
diff --git a/public/stylesheets/standard.css b/public/stylesheets/standard.css
index d214f861..7d2963cc 100644
--- a/public/stylesheets/standard.css
+++ b/public/stylesheets/standard.css
@@ -943,16 +943,9 @@ div.message {
display:none;
}
-.successor_target {
- background-image:url("../images/add_successor_off.png");
- background-repeat: no-repeat;
- background-position: center right;
-}
-
-.successor_target.hover {
- background-image:url("../images/add_successor_on.png");
- background-repeat: no-repeat;
- background-position: center right;
+.hover {
+ background: #EAEAEA;
+ font-weight: bold;
}
.context_target {
From 92bb54bbf572983aef2a57272fba688fbcc5542c Mon Sep 17 00:00:00 2001
From: Eric Allen
Date: Sun, 9 May 2010 18:59:02 -0400
Subject: [PATCH 19/64] Revert "fix cucumber story for drag and drop for
dependencies. Was broken since last change of drop target to a hidden img
that appears when dragging starts"
This reverts commit 8dbf790810e8f2b91e6f20d3897d9f32fb801ef7.
Conflicts:
app/helpers/todos_helper.rb
features/step_definitions/todo_steps.rb
---
features/step_definitions/todo_steps.rb | 11 ++---------
1 file changed, 2 insertions(+), 9 deletions(-)
diff --git a/features/step_definitions/todo_steps.rb b/features/step_definitions/todo_steps.rb
index b2bd9d24..54fec93c 100644
--- a/features/step_definitions/todo_steps.rb
+++ b/features/step_definitions/todo_steps.rb
@@ -37,15 +37,8 @@ When /^I drag "(.*)" to "(.*)"$/ do |dragged, target|
drag_id = Todo.find_by_description(dragged).id
drop_id = Todo.find_by_description(target).id
drag_name = "xpath=//div[@id='line_todo_#{drag_id}']//img[@class='grip']"
- # xpath does not seem to work here... reverting to css
- # xpath=//div[@id='line_todo_#{drop_id}']//img[@class='successor_target']
- drop_name = "css=div#line_todo_#{drop_id} img.successor_target"
-
- # HACK: the target img is hidden until drag starts. We need to show the img or the
- # xpath will not find it
- js="$('div#line_todo_#{drop_id} img.successor_target').show();"
- selenium.get_eval "(function() {with(this) {#{js}}}).call(selenium.browserbot.getCurrentWindow());"
-
+ drop_name = "xpath=//div[@id='line_todo_#{drop_id}']//div[@class='description']"
+
selenium.drag_and_drop_to_object(drag_name, drop_name)
arrow = "xpath=//div[@id='line_todo_#{drop_id}']/div/a[@class='show_successors']/img"
From cfc6d117b815c43eccdc65168e0370c23a658adc Mon Sep 17 00:00:00 2001
From: Reinier Balt
Date: Thu, 13 May 2010 18:24:26 +0200
Subject: [PATCH 20/64] fix #1027. Several tests were broken because of the
more strict validations on the recurring_todo model
---
app/models/recurring_todo.rb | 1 -
test/fixtures/recurring_todos.yml | 14 +++++++++-----
test/functional/login_controller_test.rb | 2 +-
test/functional/recurring_todos_controller_test.rb | 5 +++++
test/functional/todos_controller_test.rb | 8 ++++++--
test/functional/users_controller_test.rb | 8 ++++----
6 files changed, 25 insertions(+), 13 deletions(-)
diff --git a/app/models/recurring_todo.rb b/app/models/recurring_todo.rb
index 2f6d623b..4a916c6d 100644
--- a/app/models/recurring_todo.rb
+++ b/app/models/recurring_todo.rb
@@ -30,7 +30,6 @@ class RecurringTodo < ActiveRecord::Base
validates_presence_of :description
validates_presence_of :recurring_period
validates_presence_of :target
- validates_presence_of :recurring_period
validates_presence_of :ends_on
validates_presence_of :context
diff --git a/test/fixtures/recurring_todos.yml b/test/fixtures/recurring_todos.yml
index db630d68..9597d674 100644
--- a/test/fixtures/recurring_todos.yml
+++ b/test/fixtures/recurring_todos.yml
@@ -1,4 +1,3 @@
-<%
def today
Time.zone.now.beginning_of_day.to_s(:db)
@@ -30,7 +29,7 @@ call_bill_gates_every_day:
description: Call Bill Gates every day
notes: ~
state: active
- start_from: ~
+ start_from: <%= last_week %>
ends_on: no_end_date
end_date: ~
number_of_occurences: ~
@@ -38,6 +37,7 @@ call_bill_gates_every_day:
show_from_delta: ~
recurring_period: daily
recurrence_selector: ~
+ show_always: 0
every_other1: 1
every_other2: ~
every_other3: ~
@@ -62,6 +62,7 @@ call_bill_gates_every_workday:
number_of_occurences: ~
target: due_date
show_from_delta: ~
+ show_always: 0
recurring_period: daily
recurrence_selector: ~
every_other1: 1
@@ -82,7 +83,7 @@ call_bill_gates_every_week:
description: Call Bill Gates every week
notes: ~
state: active
- start_from: ~
+ start_from: <%= today %>
ends_on: no_end_date
end_date: ~
number_of_occurences: ~
@@ -90,6 +91,7 @@ call_bill_gates_every_week:
show_from_delta: ~
recurring_period: weekly
recurrence_selector: ~
+ show_always: 0
every_other1: 2
every_other2: ~
every_other3: ~
@@ -108,7 +110,7 @@ check_with_bill_every_last_friday_of_month:
description: Check with Bill every last friday of the month
notes: ~
state: active
- start_from: ~
+ start_from: <%= today %>
ends_on: no_end_date
end_date: ~
number_of_occurences: ~
@@ -116,6 +118,7 @@ check_with_bill_every_last_friday_of_month:
show_from_delta: 5
recurring_period: monthly
recurrence_selector: 1
+ show_always: 0
every_other1: 1
every_other2: 2
every_other3: 5
@@ -134,12 +137,13 @@ birthday_reinier:
description: Congratulate Reinier on his birthday
notes: ~
state: active
- start_from: ~
+ start_from: <%= today %>
ends_on: no_end_date
end_date: ~
number_of_occurences: ~
target: due_date
show_from_delta: 5
+ show_always: 0
recurring_period: yearly
recurrence_selector: 0
every_other1: 8
diff --git a/test/functional/login_controller_test.rb b/test/functional/login_controller_test.rb
index 50da6ae8..051bb744 100644
--- a/test/functional/login_controller_test.rb
+++ b/test/functional/login_controller_test.rb
@@ -51,7 +51,7 @@ class LoginControllerTest < ActionController::TestCase
def test_login_with_no_users_redirects_to_signup
User.delete_all
get :login
- assert_redirected_to :controller => 'users', :action => 'new'
+ assert_redirected_to signup_url
end
def test_logout
diff --git a/test/functional/recurring_todos_controller_test.rb b/test/functional/recurring_todos_controller_test.rb
index 394e72d7..ebe64ed0 100644
--- a/test/functional/recurring_todos_controller_test.rb
+++ b/test/functional/recurring_todos_controller_test.rb
@@ -50,6 +50,7 @@ class RecurringTodosControllerTest < ActionController::TestCase
"recurring_period"=>"yearly",
"recurring_show_days_before"=>"10",
"recurring_target"=>"due_date",
+ "recurring_show_always" => "1",
"start_from"=>"18/08/2008",
"weekly_every_x_week"=>"1",
"weekly_return_monday"=>"m",
@@ -110,6 +111,9 @@ class RecurringTodosControllerTest < ActionController::TestCase
@yearly.every_other1 = target_date.day
@yearly.every_other2 = target_date.month
@yearly.show_from_delta = 10
+# unless @yearly.valid?
+# @yearly.errors.each {|obj, error| puts error}
+# end
assert @yearly.save
# toggle twice to force generation of new todo
@@ -155,6 +159,7 @@ class RecurringTodosControllerTest < ActionController::TestCase
"recurring_period"=>"yearly",
"recurring_show_days_before"=>"0",
"recurring_target"=>"due_date",
+ "recurring_show_always" => "1",
"start_from"=>"1/10/2012", # adjust after 2012
"weekly_every_x_week"=>"1",
"weekly_return_monday"=>"w",
diff --git a/test/functional/todos_controller_test.rb b/test/functional/todos_controller_test.rb
index 0035f291..ec93e728 100644
--- a/test/functional/todos_controller_test.rb
+++ b/test/functional/todos_controller_test.rb
@@ -376,12 +376,16 @@ class TodosControllerTest < ActionController::TestCase
# change recurrence pattern to monthly and set show_from 2 days before due
# date this forces the next todo to be put in the tickler
recurring_todo_1.show_from_delta = 2
+ recurring_todo_1.show_always = 0
+ recurring_todo_1.target = 'due_date'
recurring_todo_1.recurring_period = 'monthly'
recurring_todo_1.recurrence_selector = 0
recurring_todo_1.every_other1 = 1
recurring_todo_1.every_other2 = 2
recurring_todo_1.every_other3 = 5
- recurring_todo_1.save
+ # use assert to catch validation errors if present. we need to replace
+ # this with a good factory implementation
+ assert recurring_todo_1.save
# mark next_todo as complete by toggle_check
xhr :post, :toggle_check, :id => next_todo.id, :_source_view => 'todo'
@@ -416,7 +420,7 @@ class TodosControllerTest < ActionController::TestCase
recurring_todo_1.recurrence_selector = 0
recurring_todo_1.every_other1 = today.day
recurring_todo_1.every_other2 = 1
- recurring_todo_1.save
+ assert recurring_todo_1.save
# mark todo_1 as complete by toggle_check, this gets rid of todo_1 that was
# not correctly created from the adjusted recurring pattern we defined
diff --git a/test/functional/users_controller_test.rb b/test/functional/users_controller_test.rb
index e53942cc..e20d9095 100644
--- a/test/functional/users_controller_test.rb
+++ b/test/functional/users_controller_test.rb
@@ -154,19 +154,19 @@ class UsersControllerTest < ActionController::TestCase
def test_create_with_invalid_password_redirects_to_new_user_page
login_as :admin_user
post :create, :user => {:login => 'newbie', :password => '', :password_confirmation => ''}
- assert_redirected_to :controller => 'users', :action => 'new'
+ assert_redirected_to signup_path
end
def test_create_with_invalid_login_does_not_add_a_new_user
login_as :admin_user
post :create, :user => {:login => 'n', :password => 'newbiepass', :password_confirmation => 'newbiepass'}
- assert_redirected_to :controller => 'users', :action => 'new'
+ assert_redirected_to signup_path
end
def test_create_with_invalid_login_redirects_to_new_user_page
login_as :admin_user
post :create, :user => {:login => 'n', :password => 'newbiepass', :password_confirmation => 'newbiepass'}
- assert_redirected_to :controller => 'users', :action => 'new'
+ assert_redirected_to signup_path
end
def test_create_with_duplicate_login_does_not_add_a_new_user
@@ -179,7 +179,7 @@ class UsersControllerTest < ActionController::TestCase
def test_create_with_duplicate_login_redirects_to_new_user_page
login_as :admin_user
post :create, :user => {:login => 'jane', :password => 'newbiepass', :password_confirmation => 'newbiepass'}
- assert_redirected_to :controller => 'users', :action => 'new'
+ assert_redirected_to signup_path
end
end
From b50a1ce26f5287d82ed6a5fbc51ee2c304f512b9 Mon Sep 17 00:00:00 2001
From: Eric Allen
Date: Mon, 17 May 2010 11:02:23 -0400
Subject: [PATCH 21/64] Fix a couple of test definitions to avoid false test
failures
State should be unspecified to default to active
Fixes #977 (again)
---
test/functional/todos_controller_test.rb | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/test/functional/todos_controller_test.rb b/test/functional/todos_controller_test.rb
index ec93e728..d4f716e7 100644
--- a/test/functional/todos_controller_test.rb
+++ b/test/functional/todos_controller_test.rb
@@ -320,7 +320,7 @@ class TodosControllerTest < ActionController::TestCase
"due(1i)"=>"2007", "due(2i)"=>"1", "due(3i)"=>"2",
"show_from(1i)"=>"", "show_from(2i)"=>"", "show_from(3i)"=>"",
"project_id"=>"1",
- "notes"=>"test notes", "description"=>"test_mobile_create_action", "state"=>"0"}}
+ "notes"=>"test notes", "description"=>"test_mobile_create_action"}}
t = Todo.find_by_description("test_mobile_create_action")
assert_not_nil t
assert_equal 2, t.context_id
@@ -347,7 +347,7 @@ class TodosControllerTest < ActionController::TestCase
"due(1i)"=>"2007", "due(2i)"=>"1", "due(3i)"=>"2",
"show_from(1i)"=>"", "show_from(2i)"=>"", "show_from(3i)"=>"",
"project_id"=>"1",
- "notes"=>"test notes", "state"=>"0"}, "tag_list"=>"test, test2"}
+ "notes"=>"test notes"}, "tag_list"=>"test, test2"}
assert_template 'todos/new'
end
From d9d08fac35fc11b10fb0b31e6b21b483a6e22450 Mon Sep 17 00:00:00 2001
From: Eric Allen
Date: Mon, 17 May 2010 11:36:41 -0400
Subject: [PATCH 22/64] Various improvements to context drag&drop
-Don't botch other fields on context change
-Better status message
-Flash context title on drop
-Drop target close to context name
-Bolder drop target border
Closes #1033
---
app/controllers/todos_controller.rb | 17 +++++++++++++++++
app/views/contexts/_context.rhtml | 2 +-
app/views/todos/update.js.rjs | 9 ++++++++-
public/javascripts/application.js | 5 ++---
public/stylesheets/standard.css | 2 +-
5 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/app/controllers/todos_controller.rb b/app/controllers/todos_controller.rb
index 480744fb..81f52b62 100644
--- a/app/controllers/todos_controller.rb
+++ b/app/controllers/todos_controller.rb
@@ -230,6 +230,23 @@ class TodosController < ApplicationController
end
end
+ def change_context
+ @todo = Todo.find(params[:todo][:id])
+ @original_item_context_id = @todo.context_id
+ @context = Context.find(params[:todo][:context_id])
+ @todo.context = @context
+ @saved = @todo.save
+
+ @context_changed = true
+ @message = "Context changed to #{@context.name}"
+ determine_remaining_in_context_count(@original_item_context_id)
+
+ respond_to do |format|
+ format.js {render :action => :update }
+ format.xml { render :xml => @todo.to_xml( :except => :user_id ) }
+ end
+ end
+
def update
@source_view = params['_source_view'] || 'todo'
init_data_for_sidebar unless mobile?
diff --git a/app/views/contexts/_context.rhtml b/app/views/contexts/_context.rhtml
index 7b33ee9a..105b66bb 100644
--- a/app/views/contexts/_context.rhtml
+++ b/app/views/contexts/_context.rhtml
@@ -10,11 +10,11 @@
<%= link_to_context( context ) %>
<% end %>
+
Currently there are no incomplete actions in this context
-
diff --git a/app/views/todos/update.js.rjs b/app/views/todos/update.js.rjs
index d15595f5..bcc80ccc 100644
--- a/app/views/todos/update.js.rjs
+++ b/app/views/todos/update.js.rjs
@@ -4,6 +4,7 @@ if @saved
status_message += ' to tickler' if @todo.deferred?
status_message = 'Added new project / ' + status_message if @new_project_created
status_message = 'Added new context / ' + status_message if @new_context_created
+ status_message = @message || status_message
page.notify :notice, status_message, 5.0
if source_view_is_one_of(:todo, :context, :tag)
@@ -46,12 +47,18 @@ if @saved
page.replace_html("badge_count", @down_count) if source_view_is :todo
# show todo in context
- page.delay(0.5) do
+ page.delay(0.3) do
page.call "todoItems.ensureContainerHeight", "c#{@original_item_context_id}items"
if source_view_is_one_of(:todo, :tag) && @todo.active?
page.call "todoItems.ensureContainerHeight", "c#{@todo.context_id}items"
page.visual_effect :highlight, dom_id(@todo), :duration => 3
end
+ if @context_changed
+ source_view do |from|
+ from.todo {page << "$('#c#{@todo.context_id} h2').effect('highlight', {}, 3000)" }
+ from.tag {page << "$('#c#{@todo.context_id} h2').effect('highlight')" }
+ end
+ end
end
else
if @original_item_was_deferred && source_view_is(:tag)
diff --git a/public/javascripts/application.js b/public/javascripts/application.js
index 4b025f51..52acc10f 100644
--- a/public/javascripts/application.js
+++ b/public/javascripts/application.js
@@ -259,9 +259,8 @@ function enable_rich_interaction(){
ui.draggable.remove();
target.block({message: null});
setTimeout(function() {target.show()}, 0);
- $.post(relative_to_root('todos/update'),
- {id: dragged_todo,
- "todo[id]": dragged_todo,
+ $.post(relative_to_root('todos/change_context'),
+ {"todo[id]": dragged_todo,
"todo[context_id]": context_id},
function(){target.unblock(); target.hide();}, 'script');
}
diff --git a/public/stylesheets/standard.css b/public/stylesheets/standard.css
index 7d2963cc..069a6ce0 100644
--- a/public/stylesheets/standard.css
+++ b/public/stylesheets/standard.css
@@ -951,7 +951,7 @@ div.message {
.context_target {
height: 15px;
margin: 4px;
- border: thick dotted #CCC;
+ border: 4px dotted #999;
}
.context_target.hover {
From ac96c5c738a9f0b92ae32ee7fba5b1d828243abd Mon Sep 17 00:00:00 2001
From: Eric Allen
Date: Tue, 18 May 2010 09:54:46 -0400
Subject: [PATCH 23/64] Fix small IE8 bug
---
public/javascripts/application.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/public/javascripts/application.js b/public/javascripts/application.js
index 52acc10f..45638756 100644
--- a/public/javascripts/application.js
+++ b/public/javascripts/application.js
@@ -231,6 +231,7 @@ function enable_rich_interaction(){
dragged_todo = ui.draggable[0].id.split('_')[2];
dropped_todo = this.id.split('_')[2];
ui.draggable.remove();
+ $('.drop_target').hide(); // IE8 doesn't call stop() in this situation
$(this).block({message: null});
$.post(relative_to_root('todos/add_predecessor'),
{successor: dragged_todo, predecessor: dropped_todo},
From 04fb281ecd28b783dd069df226261fd40967ad2c Mon Sep 17 00:00:00 2001
From: Eric Allen
Date: Sun, 4 Jul 2010 16:01:41 -0700
Subject: [PATCH 24/64] Typo that newer Gherkin caught
---
features/show_statistics.feature | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/features/show_statistics.feature b/features/show_statistics.feature
index 38bcc788..261afbbe 100644
--- a/features/show_statistics.feature
+++ b/features/show_statistics.feature
@@ -1,4 +1,4 @@
-Feature Show statistics
+Feature: Show statistics
In order to see what I have got done
As an user
I want see my statistics
From 92047e86e434664edd2da3db427cc4b079156650 Mon Sep 17 00:00:00 2001
From: Eric Allen
Date: Sun, 4 Jul 2010 20:13:32 -0700
Subject: [PATCH 25/64] Test for ticket #1043
---
features/manage_project.feature | 11 ++++++++++-
features/step_definitions/todo_steps.rb | 15 +++++++++++++++
2 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/features/manage_project.feature b/features/manage_project.feature
index 74eaaeec..88893ed5 100644
--- a/features/manage_project.feature
+++ b/features/manage_project.feature
@@ -16,4 +16,13 @@ Feature: Manage a project
When I visit the "manage me" project
And I edit the project description to "_successfull outcome_: project is *done*"
Then I should see the italic text "successfull outcome" in the project description
- And I should see the bold text "done" in the project description
\ No newline at end of file
+ And I should see the bold text "done" in the project description
+
+ # Ticket #1043
+ @selenium
+ Scenario: I can move a todo out of the current project
+ Given I have a project "foo" with 2 todos
+ When I visit the "foo" project
+ And I change the project_name field of "Todo 1" to "bar"
+ Then I should not see the todo "Todo 1"
+ And I should see the todo "Todo 2"
diff --git a/features/step_definitions/todo_steps.rb b/features/step_definitions/todo_steps.rb
index 54fec93c..98831bca 100644
--- a/features/step_definitions/todo_steps.rb
+++ b/features/step_definitions/todo_steps.rb
@@ -59,6 +59,13 @@ Then /^I should see ([0-9]+) todos$/ do |count|
end
end
+When /I change the (.*) field of "([^\"]*)" to "([^\"]*)"$/ do |field, todo_name, new_value|
+ selenium.click("//span[@class=\"todo.descr\"][.=\"#{todo_name}\"]/../../a[@class=\"icon edit_item\"]", :wait_for => :ajax, :javascript_framework => :jquery)
+ selenium.type("css=form.edit_todo_form input[name=#{field}]", new_value)
+ selenium.click("css=button.positive", :wait_for => :ajax, :javascript_framework => :jquery)
+ sleep(5)
+end
+
Then /^the dependencies of "(.*)" should include "(.*)"$/ do |child_name, parent_name|
parent = @current_user.todos.find_by_description(parent_name)
parent.should_not be_nil
@@ -81,3 +88,11 @@ Then /^I should see "([^\"]*)" within the dependencies of "([^\"]*)"$/ do |succe
xpath = "xpath=//div[@id='line_todo_#{todo.id}']//div[@id='successor_line_todo_#{successor.id}']//span"
selenium.wait_for_element(xpath, :timeout_in_seconds => 5)
end
+
+Then /^I should see the todo "([^\"]*)"$/ do |todo_description|
+ selenium.is_element_present("//span[.=\"#{todo_description}\"]").should be_true
+end
+
+Then /^I should not see the todo "([^\"]*)"$/ do |todo_description|
+ selenium.is_element_present("//span[.=\"#{todo_description}\"]").should be_false
+end
From e764a75986120f84dec8d76ca06629b37c5bd74a Mon Sep 17 00:00:00 2001
From: Eric Allen
Date: Sun, 4 Jul 2010 20:13:47 -0700
Subject: [PATCH 26/64] Case-sensitive compare screwed up source_view
Fixes #1043
---
public/javascripts/application.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/public/javascripts/application.js b/public/javascripts/application.js
index 45638756..e607f777 100644
--- a/public/javascripts/application.js
+++ b/public/javascripts/application.js
@@ -49,7 +49,7 @@ $.fn.clearForm = function() {
/* Set up authenticity token properly */
$(document).ajaxSend(function(event, request, settings) {
- if ( settings.type == 'POST' ) {
+ if ( settings.type == 'POST' || settings.type == 'post' ) {
if(typeof(AUTH_TOKEN) != 'undefined'){
settings.data = (settings.data ? settings.data + "&" : "")
+ "authenticity_token=" + encodeURIComponent( AUTH_TOKEN ) + "&"
From f10a98d8acdad6b1e89f1b64248c885c38eb76f0 Mon Sep 17 00:00:00 2001
From: Eric Allen
Date: Mon, 5 Jul 2010 08:24:58 -0700
Subject: [PATCH 27/64] Test for #1041
---
features/manage_project.feature | 8 ++++++++
features/step_definitions/project_steps.rb | 10 ++++++++++
2 files changed, 18 insertions(+)
diff --git a/features/manage_project.feature b/features/manage_project.feature
index 88893ed5..f460bd5e 100644
--- a/features/manage_project.feature
+++ b/features/manage_project.feature
@@ -26,3 +26,11 @@ Feature: Manage a project
And I change the project_name field of "Todo 1" to "bar"
Then I should not see the todo "Todo 1"
And I should see the todo "Todo 2"
+
+ # Ticket #1041
+ @selenium
+ Scenario: I can change the name of the project using the Edit Project Settings form
+ Given I have a project "bananas" with 1 todos
+ When I visit the "bananas" project
+ And I edit the project name to "cherries"
+ Then the project title should be "cherries"
diff --git a/features/step_definitions/project_steps.rb b/features/step_definitions/project_steps.rb
index 801104c9..bb200f1a 100644
--- a/features/step_definitions/project_steps.rb
+++ b/features/step_definitions/project_steps.rb
@@ -27,6 +27,12 @@ When /^I edit the project description to "([^\"]*)"$/ do |new_description|
click_button "submit_project_#{@project.id}"
end
+When /^I edit the project name to "([^\"]*)"$/ do |new_title|
+ click_link "link_edit_project_#{@project.id}"
+ fill_in "project[name]", :with => new_title
+ click_button "submit_project_#{@project.id}"
+end
+
Then /^I should see the bold text "([^\"]*)" in the project description$/ do |bold|
xpath="//div[@class='project_description']/p/strong"
@@ -44,3 +50,7 @@ Then /^I should see the italic text "([^\"]*)" in the project description$/ do |
italic_text.should =~ /#{italic}/
end
+
+Then /^the project title should be "(.*)"$/ do |title|
+ selenium.get_text("css=h2#project_name").should == title
+end
From 1cd748d7a27ce27369986a6afb3250dd131cdff0 Mon Sep 17 00:00:00 2001
From: Eric Allen
Date: Mon, 5 Jul 2010 09:58:25 -0700
Subject: [PATCH 28/64] Fix #1041
---
app/views/projects/update.js.rjs | 6 +++++-
features/step_definitions/project_steps.rb | 5 ++++-
public/javascripts/application.js | 4 ++--
3 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/app/views/projects/update.js.rjs b/app/views/projects/update.js.rjs
index a8b4d3a8..2d554dea 100644
--- a/app/views/projects/update.js.rjs
+++ b/app/views/projects/update.js.rjs
@@ -28,5 +28,9 @@ else
page << "defaultTags = #{default_tags_for_autocomplete};"
end
-page.replace_html "sidebar", :file => 'sidebar/sidebar.html.erb'
+page['default_project_name_id'].value = @project.name
+page['todo_project_name'].value = @project.name
+page.replace_html "project_name", @project.name
+page.replace_html "sidebar", :file => 'sidebar/sidebar.html.erb'
+page << "enable_rich_interaction();"
diff --git a/features/step_definitions/project_steps.rb b/features/step_definitions/project_steps.rb
index bb200f1a..9ec28edc 100644
--- a/features/step_definitions/project_steps.rb
+++ b/features/step_definitions/project_steps.rb
@@ -30,7 +30,10 @@ end
When /^I edit the project name to "([^\"]*)"$/ do |new_title|
click_link "link_edit_project_#{@project.id}"
fill_in "project[name]", :with => new_title
- click_button "submit_project_#{@project.id}"
+ selenium.click "submit_project_#{@project.id}",
+ :wait_for => :text,
+ :element => "flash",
+ :text => "Project saved"
end
Then /^I should see the bold text "([^\"]*)" in the project description$/ do |bold|
diff --git a/public/javascripts/application.js b/public/javascripts/application.js
index e607f777..30d836f5 100644
--- a/public/javascripts/application.js
+++ b/public/javascripts/application.js
@@ -273,6 +273,8 @@ function enable_rich_interaction(){
/* Reset auto updater */
field_touched = false;
+
+ $('h2#project_name').editable(save_project_name, {style: 'padding:0px', submit: "OK"});
}
/* Auto-refresh */
@@ -462,8 +464,6 @@ $(document).ready(function() {
return(value);
};
- $('h2#project_name').editable(save_project_name, {style: 'padding:0px', submit: "OK"});
-
$('.alphabetize_link').click(function(evt){
evt.preventDefault();
if(confirm('Are you sure that you want to sort these projects alphabetically? This will replace the existing sort order.')){
From e2443dace452a98944f70306ff3f8f1d6037face Mon Sep 17 00:00:00 2001
From: Eric Allen
Date: Mon, 5 Jul 2010 09:58:35 -0700
Subject: [PATCH 29/64] Get rid of some autocomplete leftovers
---
app/views/projects/update.js.rjs | 2 --
app/views/projects/update_project_name.js.rjs | 2 --
2 files changed, 4 deletions(-)
diff --git a/app/views/projects/update.js.rjs b/app/views/projects/update.js.rjs
index 2d554dea..079b98ee 100644
--- a/app/views/projects/update.js.rjs
+++ b/app/views/projects/update.js.rjs
@@ -24,8 +24,6 @@ else
page['#todo_project_name'].value = @project.name
page['tag_list'].value = @project.default_tags if @project.default_tags
page << "$('input[name=default_context_name]').val('#{@project.default_context.name}');" if @project.default_context
- page << "defaultContexts = #{default_contexts_for_autocomplete};"
- page << "defaultTags = #{default_tags_for_autocomplete};"
end
page['default_project_name_id'].value = @project.name
diff --git a/app/views/projects/update_project_name.js.rjs b/app/views/projects/update_project_name.js.rjs
index 5a41572c..85ed34e7 100644
--- a/app/views/projects/update_project_name.js.rjs
+++ b/app/views/projects/update_project_name.js.rjs
@@ -1,8 +1,6 @@
page['default_project_name_id'].value = @project.name
page['todo_project_name'].value = @project.name
-# renew project auto complete array
-page << "var projectNames = #{project_names_for_autocomplete};"
page << "enable_rich_interaction();"
status_message = "Name of project was changed"
From 157595be50b777d4753f472717a61079dd85a200 Mon Sep 17 00:00:00 2001
From: Reinier Balt
Date: Fri, 16 Jul 2010 15:38:34 +0200
Subject: [PATCH 30/64] fix timing issue on context selenium step
---
features/step_definitions/context_steps.rb | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/features/step_definitions/context_steps.rb b/features/step_definitions/context_steps.rb
index a75f780c..ba025d12 100644
--- a/features/step_definitions/context_steps.rb
+++ b/features/step_definitions/context_steps.rb
@@ -44,10 +44,20 @@ end
When /^I edit the context to rename it to "([^\"]*)"$/ do |new_name|
click_link "edit_context_#{@context.id}"
- fill_in "context_name", :with => new_name
- click_button "submit_context_#{@context.id}"
+
wait_for do
- selenium.is_visible("flash")
+ selenium.is_element_present("submit_context_#{@context.id}")
+ end
+
+ fill_in "context_name", :with => new_name
+
+ selenium.click "submit_context_#{@context.id}",
+ :wait_for => :text,
+ :element => "flash",
+ :text => "Context saved"
+
+ wait_for do
+ selenium.is_element_present("edit_context_#{@context.id}")
end
end
From ceb4529a7c6837ff47000d6d765ad1fed990b4b1 Mon Sep 17 00:00:00 2001
From: Reinier Balt
Date: Mon, 26 Jul 2010 21:36:48 +0200
Subject: [PATCH 31/64] Add warning that deleting a context will also delete
all actions within it. Fixes #1049. Thanks edgimar for reporting this.
---
app/views/contexts/_context_listing.rhtml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/views/contexts/_context_listing.rhtml b/app/views/contexts/_context_listing.rhtml
index df90a138..f4c8ce5c 100644
--- a/app/views/contexts/_context_listing.rhtml
+++ b/app/views/contexts/_context_listing.rhtml
@@ -26,7 +26,7 @@
:with => "'_source_view=#{@source_view}'",
:before => "$('#{dom_id(context)}').block({message:null});",
:complete => "$('#{dom_id(context)}').unblock();",
- :confirm => "Are you sure that you want to delete the context '#{context.name}'?",
+ :confirm => "Are you sure that you want to delete the context '#{context.name}'? Be aware that this will also delete all actions in this context!",
:html => { :id => dom_id(context, 'delete') }
) %>
<%= link_to_remote(
From 6334a3f7d74f5f89653bd8a1f8749fa82db7785c Mon Sep 17 00:00:00 2001
From: Reinier Balt
Date: Mon, 26 Jul 2010 22:09:22 +0200
Subject: [PATCH 32/64] set defaults right when adding a new action on the
mobile interface from the context or project page. Fixes #1051.
We need tests for this :-)
---
app/views/layouts/mobile.m.erb | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/app/views/layouts/mobile.m.erb b/app/views/layouts/mobile.m.erb
index 75cd4049..8bacf7c9 100644
--- a/app/views/layouts/mobile.m.erb
+++ b/app/views/layouts/mobile.m.erb
@@ -1,5 +1,5 @@
<%
- new_todo_params = {}
+ new_todo_params = {:format => :m}
new_todo_params[:from_project] = @mobile_from_project if @mobile_from_project
new_todo_params[:from_context] = @mobile_from_context if @mobile_from_context
-%>
@@ -16,7 +16,7 @@
From 551eab19a5b6fe92e3a7aaafae659c4b42cacc94 Mon Sep 17 00:00:00 2001
From: Reinier Balt
Date: Thu, 22 Jul 2010 13:54:26 +0200
Subject: [PATCH 36/64] regenerate cucumber setup
---
config/cucumber.yml | 9 +-
config/environments/cucumber.rb | 9 +-
features/step_definitions/web_steps.rb | 134 ++++++++++++++-----------
features/support/env.rb | 14 +--
features/support/paths.rb | 50 +++++----
lib/tasks/cucumber.rake | 71 +++++++------
6 files changed, 152 insertions(+), 135 deletions(-)
diff --git a/config/cucumber.yml b/config/cucumber.yml
index b639c79d..621a14ce 100644
--- a/config/cucumber.yml
+++ b/config/cucumber.yml
@@ -1,9 +1,8 @@
<%
rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : ""
-rerun_opts = rerun.to_s.strip.empty? ? "--format progress " : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}"
-requires = "-r features/support/env.rb -r features/step_definitions"
-std_opts = "#{rerun_opts} #{requires} --format rerun --out rerun.txt --strict --tags ~@wip"
+rerun_opts = rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}"
+std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} --strict --tags ~@wip"
%>
-default: <%= std_opts %> --tags ~@selenium
-selenium: <%= std_opts %> --tags @selenium -r features/support/selenium.rb
+default: <%= std_opts %> features
wip: --tags @wip:3 --wip features
+rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip
diff --git a/config/environments/cucumber.rb b/config/environments/cucumber.rb
index f3ddb3bb..b1104b29 100644
--- a/config/environments/cucumber.rb
+++ b/config/environments/cucumber.rb
@@ -21,8 +21,9 @@ config.action_controller.allow_forgery_protection = false
# ActionMailer::Base.deliveries array.
config.action_mailer.delivery_method = :test
-config.gem 'cucumber-rails', :lib => false, :version => '>=0.2.3' unless File.directory?(File.join(Rails.root, 'vendor/plugins/cucumber-rails'))
-config.gem 'webrat', :lib => false, :version => '>=0.6.0' unless File.directory?(File.join(Rails.root, 'vendor/plugins/webrat'))
-config.gem 'rspec', :lib => false, :version => '>=1.2.9' unless File.directory?(File.join(Rails.root, 'vendor/plugins/rspec'))
-config.gem 'rspec-rails', :lib => false, :version => '>=1.2.9' unless File.directory?(File.join(Rails.root, 'vendor/plugins/rspec-rails'))
+config.gem 'cucumber-rails', :lib => false, :version => '>=0.3.2' unless File.directory?(File.join(Rails.root, 'vendor/plugins/cucumber-rails'))
+config.gem 'database_cleaner', :lib => false, :version => '>=0.5.0' unless File.directory?(File.join(Rails.root, 'vendor/plugins/database_cleaner'))
+config.gem 'webrat', :lib => false, :version => '>=0.7.0' unless File.directory?(File.join(Rails.root, 'vendor/plugins/webrat'))
+config.gem 'rspec', :lib => false, :version => '>=1.3.0' unless File.directory?(File.join(Rails.root, 'vendor/plugins/rspec'))
+config.gem 'rspec-rails', :lib => false, :version => '>=1.3.2' unless File.directory?(File.join(Rails.root, 'vendor/plugins/rspec-rails'))
diff --git a/features/step_definitions/web_steps.rb b/features/step_definitions/web_steps.rb
index 2996dd6e..b7570961 100644
--- a/features/step_definitions/web_steps.rb
+++ b/features/step_definitions/web_steps.rb
@@ -6,6 +6,7 @@
require 'uri'
+require 'cgi'
require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths"))
# Commonly used webrat steps
@@ -19,23 +20,23 @@ When /^(?:|I )go to (.+)$/ do |page_name|
visit path_to(page_name)
end
-When /^(?:|I )press "([^\"]*)"$/ do |button|
+When /^(?:|I )press "([^"]*)"$/ do |button|
click_button(button)
end
-When /^(?:|I )follow "([^\"]*)"$/ do |link|
+When /^(?:|I )follow "([^"]*)"$/ do |link|
click_link(link)
end
-When /^(?:|I )follow "([^\"]*)" within "([^\"]*)"$/ do |link, parent|
+When /^(?:|I )follow "([^"]*)" within "([^"]*)"$/ do |link, parent|
click_link_within(parent, link)
end
-When /^(?:|I )fill in "([^\"]*)" with "([^\"]*)"$/ do |field, value|
+When /^(?:|I )fill in "([^"]*)" with "([^"]*)"$/ do |field, value|
fill_in(field, :with => value)
end
-When /^(?:|I )fill in "([^\"]*)" for "([^\"]*)"$/ do |value, field|
+When /^(?:|I )fill in "([^"]*)" for "([^"]*)"$/ do |value, field|
fill_in(field, :with => value)
end
@@ -56,13 +57,13 @@ When /^(?:|I )fill in the following:$/ do |fields|
end
end
-When /^(?:|I )select "([^\"]*)" from "([^\"]*)"$/ do |value, field|
+When /^(?:|I )select "([^"]*)" from "([^"]*)"$/ do |value, field|
select(value, :from => field)
end
# Use this step in conjunction with Rail's datetime_select helper. For example:
# When I select "December 25, 2008 10:00" as the date and time
-When /^(?:|I )select "([^\"]*)" as the date and time$/ do |time|
+When /^(?:|I )select "([^"]*)" as the date and time$/ do |time|
select_datetime(time)
end
@@ -75,7 +76,7 @@ end
# The following steps would fill out the form:
# When I select "November 23, 2004 11:20" as the "Preferred" date and time
# And I select "November 25, 2004 10:30" as the "Alternative" date and time
-When /^(?:|I )select "([^\"]*)" as the "([^\"]*)" date and time$/ do |datetime, datetime_label|
+When /^(?:|I )select "([^"]*)" as the "([^"]*)" date and time$/ do |datetime, datetime_label|
select_datetime(datetime, :from => datetime_label)
end
@@ -83,46 +84,46 @@ end
# When I select "2:20PM" as the time
# Note: Rail's default time helper provides 24-hour time-- not 12 hour time. Webrat
# will convert the 2:20PM to 14:20 and then select it.
-When /^(?:|I )select "([^\"]*)" as the time$/ do |time|
+When /^(?:|I )select "([^"]*)" as the time$/ do |time|
select_time(time)
end
# Use this step when using multiple time_select helpers on a page or you want to
# specify the name of the time on the form. For example:
# When I select "7:30AM" as the "Gym" time
-When /^(?:|I )select "([^\"]*)" as the "([^\"]*)" time$/ do |time, time_label|
+When /^(?:|I )select "([^"]*)" as the "([^"]*)" time$/ do |time, time_label|
select_time(time, :from => time_label)
end
# Use this step in conjunction with Rail's date_select helper. For example:
# When I select "February 20, 1981" as the date
-When /^(?:|I )select "([^\"]*)" as the date$/ do |date|
+When /^(?:|I )select "([^"]*)" as the date$/ do |date|
select_date(date)
end
# Use this step when using multiple date_select helpers on one page or
# you want to specify the name of the date on the form. For example:
# When I select "April 26, 1982" as the "Date of Birth" date
-When /^(?:|I )select "([^\"]*)" as the "([^\"]*)" date$/ do |date, date_label|
+When /^(?:|I )select "([^"]*)" as the "([^"]*)" date$/ do |date, date_label|
select_date(date, :from => date_label)
end
-When /^(?:|I )check "([^\"]*)"$/ do |field|
+When /^(?:|I )check "([^"]*)"$/ do |field|
check(field)
end
-When /^(?:|I )uncheck "([^\"]*)"$/ do |field|
+When /^(?:|I )uncheck "([^"]*)"$/ do |field|
uncheck(field)
end
-When /^(?:|I )choose "([^\"]*)"$/ do |field|
+When /^(?:|I )choose "([^"]*)"$/ do |field|
choose(field)
end
# Adds support for validates_attachment_content_type. Without the mime-type getting
# passed to attach_file() you will get a "Photo file is not one of the allowed file types."
# error message
-When /^(?:|I )attach the file "([^\"]*)" to "([^\"]*)"$/ do |path, field|
+When /^(?:|I )attach the file "([^"]*)" to "([^"]*)"$/ do |path, field|
type = path.split(".")[1]
case type
@@ -139,123 +140,142 @@ When /^(?:|I )attach the file "([^\"]*)" to "([^\"]*)"$/ do |path, field|
attach_file(field, path, type)
end
-Then /^(?:|I )should see "([^\"]*)"$/ do |text|
- if defined?(Spec::Rails::Matchers)
+Then /^(?:|I )should see "([^"]*)"$/ do |text|
+ if response.respond_to? :should
response.should contain(text)
else
assert_contain text
end
end
-Then /^(?:|I )should see "([^\"]*)" within "([^\"]*)"$/ do |text, selector|
+Then /^(?:|I )should see "([^"]*)" within "([^"]*)"$/ do |text, selector|
within(selector) do |content|
- if defined?(Spec::Rails::Matchers)
+ if content.respond_to? :should
content.should contain(text)
else
- assert content.include?(text)
+ hc = Webrat::Matchers::HasContent.new(text)
+ assert hc.matches?(content), hc.failure_message
end
end
end
Then /^(?:|I )should see \/([^\/]*)\/$/ do |regexp|
regexp = Regexp.new(regexp)
- if defined?(Spec::Rails::Matchers)
+ if response.respond_to? :should
response.should contain(regexp)
else
- assert_contain regexp
+ assert_match(regexp, response_body)
end
end
-Then /^(?:|I )should see \/([^\/]*)\/ within "([^\"]*)"$/ do |regexp, selector|
+Then /^(?:|I )should see \/([^\/]*)\/ within "([^"]*)"$/ do |regexp, selector|
within(selector) do |content|
regexp = Regexp.new(regexp)
- if defined?(Spec::Rails::Matchers)
+ if content.respond_to? :should
content.should contain(regexp)
else
- assert content =~ regexp
+ assert_match(regexp, content)
end
end
end
-Then /^(?:|I )should not see "([^\"]*)"$/ do |text|
- if defined?(Spec::Rails::Matchers)
+Then /^(?:|I )should not see "([^"]*)"$/ do |text|
+ if response.respond_to? :should_not
response.should_not contain(text)
else
- assert_not_contain text
+ assert_not_contain(text)
end
end
-Then /^(?:|I )should not see "([^\"]*)" within "([^\"]*)"$/ do |text, selector|
+Then /^(?:|I )should not see "([^"]*)" within "([^"]*)"$/ do |text, selector|
within(selector) do |content|
- if defined?(Spec::Rails::Matchers)
- content.should_not contain(text)
+ if content.respond_to? :should_not
+ content.should_not contain(text)
else
- assert !content.include?(text)
+ hc = Webrat::Matchers::HasContent.new(text)
+ assert !hc.matches?(content), hc.negative_failure_message
end
end
end
Then /^(?:|I )should not see \/([^\/]*)\/$/ do |regexp|
regexp = Regexp.new(regexp)
- if defined?(Spec::Rails::Matchers)
+ if response.respond_to? :should_not
response.should_not contain(regexp)
else
- assert_not_contain regexp
+ assert_not_contain(regexp)
end
end
-Then /^(?:|I )should not see \/([^\/]*)\/ within "([^\"]*)"$/ do |regexp, selector|
+Then /^(?:|I )should not see \/([^\/]*)\/ within "([^"]*)"$/ do |regexp, selector|
within(selector) do |content|
regexp = Regexp.new(regexp)
- if defined?(Spec::Rails::Matchers)
+ if content.respond_to? :should_not
content.should_not contain(regexp)
else
- assert content !~ regexp
+ assert_no_match(regexp, content)
end
end
end
-Then /^the "([^\"]*)" field should contain "([^\"]*)"$/ do |field, value|
- if defined?(Spec::Rails::Matchers)
- field_labeled(field).value.should =~ /#{value}/
+Then /^the "([^"]*)" field should contain "([^"]*)"$/ do |field, value|
+ field_value = field_labeled(field).value
+ if field_value.respond_to? :should
+ field_value.should =~ /#{value}/
else
- assert_match(/#{value}/, field_labeled(field).value)
+ assert_match(/#{value}/, field_value)
end
end
-Then /^the "([^\"]*)" field should not contain "([^\"]*)"$/ do |field, value|
- if defined?(Spec::Rails::Matchers)
- field_labeled(field).value.should_not =~ /#{value}/
+Then /^the "([^"]*)" field should not contain "([^"]*)"$/ do |field, value|
+ field_value = field_labeled(field).value
+ if field_value.respond_to? :should_not
+ field_value.should_not =~ /#{value}/
else
- assert_no_match(/#{value}/, field_labeled(field).value)
+ assert_no_match(/#{value}/, field_value)
end
end
-Then /^the "([^\"]*)" checkbox should be checked$/ do |label|
- if defined?(Spec::Rails::Matchers)
- field_labeled(label).should be_checked
+Then /^the "([^"]*)" checkbox should be checked$/ do |label|
+ field = field_labeled(label)
+ if field.respond_to? :should
+ field.should be_checked
else
- assert field_labeled(label).checked?
+ assert field.checked?
end
end
-Then /^the "([^\"]*)" checkbox should not be checked$/ do |label|
- if defined?(Spec::Rails::Matchers)
- field_labeled(label).should_not be_checked
+Then /^the "([^"]*)" checkbox should not be checked$/ do |label|
+ field = field_labeled(label)
+ if field.respond_to? :should_not
+ field.should_not be_checked
else
- assert !field_labeled(label).checked?
+ assert !field.checked?
end
end
Then /^(?:|I )should be on (.+)$/ do |page_name|
- current_path = URI.parse(current_url).select(:path, :query).compact.join('?')
- if defined?(Spec::Rails::Matchers)
+ current_path = URI.parse(current_url).path
+ if current_path.respond_to? :should
current_path.should == path_to(page_name)
else
assert_equal path_to(page_name), current_path
end
end
+Then /^(?:|I )should have the following query string:$/ do |expected_pairs|
+ query = URI.parse(current_url).query
+ actual_params = query ? CGI.parse(query) : {}
+ expected_params = {}
+ expected_pairs.rows_hash.each_pair{|k,v| expected_params[k] = v.split(',')}
+
+ if actual_params.respond_to? :should
+ actual_params.should == expected_params
+ else
+ assert_equal expected_params, actual_params
+ end
+end
+
Then /^show me the page$/ do
save_and_open_page
-end
\ No newline at end of file
+end
diff --git a/features/support/env.rb b/features/support/env.rb
index 74765593..536cac89 100644
--- a/features/support/env.rb
+++ b/features/support/env.rb
@@ -15,7 +15,6 @@ require 'cucumber/web/tableish'
require 'webrat'
require 'webrat/core/matchers'
-# require 'cucumber/webrat/element_locator' # Deprecated in favor of #tableish - remove this line if you don't use #element_at or #table_at
Webrat.configure do |config|
config.mode = :rails
@@ -47,11 +46,12 @@ ActionController::Base.allow_rescue = false
# subsequent scenarios. If you do this, we recommend you create a Before
# block that will explicitly put your database in a known state.
Cucumber::Rails::World.use_transactional_fixtures = true
-
# How to clean your database when transactions are turned off. See
# http://github.com/bmabey/database_cleaner for more info.
-require 'database_cleaner'
-DatabaseCleaner.strategy = :truncation
-
-require 'factory_girl'
-Dir.glob(File.join(File.dirname(__FILE__), '../../spec/factories/*.rb')).each {|f| require f }
+if defined?(ActiveRecord::Base)
+ begin
+ require 'database_cleaner'
+ DatabaseCleaner.strategy = :truncation
+ rescue LoadError => ignore_if_database_cleaner_not_present
+ end
+end
diff --git a/features/support/paths.rb b/features/support/paths.rb
index 19142887..06b3efb0 100644
--- a/features/support/paths.rb
+++ b/features/support/paths.rb
@@ -1,33 +1,31 @@
module NavigationHelpers
+ # Maps a name to a path. Used by the
+ #
+ # When /^I go to (.+)$/ do |page_name|
+ #
+ # step definition in web_steps.rb
+ #
def path_to(page_name)
case page_name
-
- when /the homepage/
- root_path
- when /the home page/
- root_path
- when /the statistics page/
- stats_path
- when /the signup page/
- signup_path
- when /the login page/
- login_path
- when /the notes page/
- notes_path
- when /the contexts page/
- contexts_path
- when /the manage users page/
- users_path
- when /the repeating todos page/
- recurring_todos_path
- when /the integrations page/
- integrations_path
-
- # Add more page name => path mappings here
-
+
+ when /the home\s?page/
+ '/'
+
+ # Add more mappings here.
+ # Here is an example that pulls values out of the Regexp:
+ #
+ # when /^(.*)'s profile page$/i
+ # user_profile_path(User.find_by_login($1))
+
else
- raise "Can't find mapping from \"#{page_name}\" to a path.\n" +
- "Now, go and add a mapping in features/support/paths.rb"
+ begin
+ page_name =~ /the (.*) page/
+ path_components = $1.split(/\s+/)
+ self.send(path_components.push('path').join('_').to_sym)
+ rescue Object => e
+ raise "Can't find mapping from \"#{page_name}\" to a path.\n" +
+ "Now, go and add a mapping in #{__FILE__}"
+ end
end
end
end
diff --git a/lib/tasks/cucumber.rake b/lib/tasks/cucumber.rake
index 1a04fc73..7db1a557 100644
--- a/lib/tasks/cucumber.rake
+++ b/lib/tasks/cucumber.rake
@@ -7,48 +7,47 @@
unless ARGV.any? {|a| a =~ /^gems/} # Don't load anything when running the gems:* tasks
- vendored_cucumber_bin = Dir["#{RAILS_ROOT}/vendor/{gems,plugins}/cucumber*/bin/cucumber"].first
- $LOAD_PATH.unshift(File.dirname(vendored_cucumber_bin) + '/../lib') unless vendored_cucumber_bin.nil?
+vendored_cucumber_bin = Dir["#{Rails.root}/vendor/{gems,plugins}/cucumber*/bin/cucumber"].first
+$LOAD_PATH.unshift(File.dirname(vendored_cucumber_bin) + '/../lib') unless vendored_cucumber_bin.nil?
- begin
- require 'cucumber/rake/task'
+begin
+ require 'cucumber/rake/task'
- namespace :cucumber do
- Cucumber::Rake::Task.new({:ok => 'db:test:prepare'}, 'Run features that should pass') do |t|
- t.binary = vendored_cucumber_bin # If nil, the gem's binary is used.
- t.fork = true # You may get faster startup if you set this to false
- t.profile = 'default'
- end
-
- Cucumber::Rake::Task.new({:wip => 'db:test:prepare'}, 'Run features that are being worked on') do |t|
- t.binary = vendored_cucumber_bin
- t.fork = true # You may get faster startup if you set this to false
- t.profile = 'wip'
- end
-
- Cucumber::Rake::Task.new({:selenium => 'db:test:prepare'}, 'Run features that require selenium') do |t|
- t.binary = vendored_cucumber_bin
- t.fork = true # You may get faster startup if you set this to false
- t.profile = 'selenium'
- ENV['RAILS_ENV'] = "selenium" # switch to selenium environment
- end
-
- desc 'Run all features'
- task :all => [:ok, :wip]
+ namespace :cucumber do
+ Cucumber::Rake::Task.new({:ok => 'db:test:prepare'}, 'Run features that should pass') do |t|
+ t.binary = vendored_cucumber_bin # If nil, the gem's binary is used.
+ t.fork = true # You may get faster startup if you set this to false
+ t.profile = 'default'
end
- desc 'Alias for cucumber:ok'
- task :cucumber => 'cucumber:ok'
- task :default => :cucumber
+ Cucumber::Rake::Task.new({:wip => 'db:test:prepare'}, 'Run features that are being worked on') do |t|
+ t.binary = vendored_cucumber_bin
+ t.fork = true # You may get faster startup if you set this to false
+ t.profile = 'wip'
+ end
- task :features => :cucumber do
- STDERR.puts "*** The 'features' task is deprecated. See rake -T cucumber ***"
- end
- rescue LoadError
- desc 'cucumber rake task not available (cucumber not installed)'
- task :cucumber do
- abort 'Cucumber rake task is not available. Be sure to install cucumber as a gem or plugin'
+ Cucumber::Rake::Task.new({:rerun => 'db:test:prepare'}, 'Record failing features and run only them if any exist') do |t|
+ t.binary = vendored_cucumber_bin
+ t.fork = true # You may get faster startup if you set this to false
+ t.profile = 'rerun'
end
+
+ desc 'Run all features'
+ task :all => [:ok, :wip]
end
+ desc 'Alias for cucumber:ok'
+ task :cucumber => 'cucumber:ok'
+
+ task :default => :cucumber
+
+ task :features => :cucumber do
+ STDERR.puts "*** The 'features' task is deprecated. See rake -T cucumber ***"
+ end
+rescue LoadError
+ desc 'cucumber rake task not available (cucumber not installed)'
+ task :cucumber do
+ abort 'Cucumber rake task is not available. Be sure to install cucumber as a gem or plugin'
+ end
+end
end
From e2841e31eb390fa6d73cffd9167c5d39477058f3 Mon Sep 17 00:00:00 2001
From: Reinier Balt
Date: Tue, 27 Jul 2010 23:32:22 +0200
Subject: [PATCH 37/64] finish upgrade of selenium
these were manual cherry-picks of the rails upgrade work.
---
config/cucumber.yml | 3 ++-
config/environment.rb | 4 ++--
config/environments/development.rb | 2 +-
config/environments/selenium.rb | 13 ++++++-----
config/environments/test.rb | 21 ++++-------------
features/support/init_factory_girl.rb | 2 ++
features/support/paths.rb | 18 ++++++++++++++-
features/support/selenium.rb | 33 ++++++++++-----------------
lib/tasks/cucumber-tracks.rake | 32 ++++++++++++++++++++++++++
9 files changed, 80 insertions(+), 48 deletions(-)
create mode 100644 features/support/init_factory_girl.rb
create mode 100644 lib/tasks/cucumber-tracks.rake
diff --git a/config/cucumber.yml b/config/cucumber.yml
index 621a14ce..97f4fd48 100644
--- a/config/cucumber.yml
+++ b/config/cucumber.yml
@@ -3,6 +3,7 @@ rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : ""
rerun_opts = rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}"
std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} --strict --tags ~@wip"
%>
-default: <%= std_opts %> features
+default: <%= std_opts %> features --tags ~@selenium
+selenium: <%= std_opts %> features --tags @selenium
wip: --tags @wip:3 --wip features
rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip
diff --git a/config/environment.rb b/config/environment.rb
index 0afd8fc8..590161f4 100644
--- a/config/environment.rb
+++ b/config/environment.rb
@@ -32,8 +32,8 @@ Rails::Initializer.run do |config|
config.action_controller.session_store = :active_record_store
config.action_controller.session = {
- :key => '_tracks_session_id',
- :secret => SITE_CONFIG['salt'] * (30.0 / SITE_CONFIG['salt'].length).ceil #must be at least 30 characters
+ :key => '_tracks_session_id',
+ :secret => SITE_CONFIG['salt'] * (30.0 / SITE_CONFIG['salt'].length).ceil #must be at least 30 characters
}
config.action_controller.relative_url_root = SITE_CONFIG['subdir'] if SITE_CONFIG['subdir']
diff --git a/config/environments/development.rb b/config/environments/development.rb
index 8c3aa19f..c30f67cf 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -14,4 +14,4 @@ config.action_controller.perform_caching = false
config.action_mailer.raise_delivery_errors = false
# Unique cookies
-ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS[:session_key] = "TrackDev"
\ No newline at end of file
+config.action_controller.session = { :key => 'TracksDev' }
\ No newline at end of file
diff --git a/config/environments/selenium.rb b/config/environments/selenium.rb
index b933322c..004b1ee6 100644
--- a/config/environments/selenium.rb
+++ b/config/environments/selenium.rb
@@ -21,10 +21,11 @@ config.action_controller.allow_forgery_protection = false
# ActionMailer::Base.deliveries array.
config.action_mailer.delivery_method = :test
-config.gem 'cucumber-rails', :lib => false, :version => '>=0.2.3' unless File.directory?(File.join(Rails.root, 'vendor/plugins/cucumber-rails'))
-config.gem 'webrat', :lib => false, :version => '>=0.6.0' unless File.directory?(File.join(Rails.root, 'vendor/plugins/webrat'))
-config.gem 'rspec', :lib => false, :version => '>=1.2.9' unless File.directory?(File.join(Rails.root, 'vendor/plugins/rspec'))
-config.gem 'rspec-rails', :lib => false, :version => '>=1.2.9' unless File.directory?(File.join(Rails.root, 'vendor/plugins/rspec-rails'))
-
-config.gem 'database_cleaner', :lib => false, :version => '>=0.2.3' unless File.directory?(File.join(Rails.root, 'vendor/plugins/database_cleaner'))
+# Unique cookies
+config.action_controller.session = { :key => 'TracksSelenium' }
+config.gem 'cucumber-rails', :lib => false, :version => '>=0.3.2' unless File.directory?(File.join(Rails.root, 'vendor/plugins/cucumber-rails'))
+config.gem 'database_cleaner', :lib => false, :version => '>=0.5.0' unless File.directory?(File.join(Rails.root, 'vendor/plugins/database_cleaner'))
+config.gem 'webrat', :lib => false, :version => '>=0.7.0' unless File.directory?(File.join(Rails.root, 'vendor/plugins/webrat'))
+config.gem 'rspec', :lib => false, :version => '>=1.3.0' unless File.directory?(File.join(Rails.root, 'vendor/plugins/rspec'))
+config.gem 'rspec-rails', :lib => false, :version => '>=1.3.2' unless File.directory?(File.join(Rails.root, 'vendor/plugins/rspec-rails'))
\ No newline at end of file
diff --git a/config/environments/test.rb b/config/environments/test.rb
index f03567bd..8555cc9b 100644
--- a/config/environments/test.rb
+++ b/config/environments/test.rb
@@ -19,19 +19,8 @@ config.action_mailer.delivery_method = :test
# Disable request forgery protection in test environment
config.action_controller.allow_forgery_protection = false
-# We store more than 4K of data in the session during some tests.
-# Override the hard-coded cookie session store to use a memory store for tests.
-# See http://groups.google.com/group/rubyonrails-talk/browse_thread/thread/5519ca7fd4dde3c1
-class ActionController::RackRequest
- DEFAULT_SESSION_OPTIONS = {
- #:database_manager => CGI::Session::MemoryStore, # store data in memory
- :prefix => "ruby_sess.", # prefix session file names
- :session_path => "/", # available to all paths in app
- :session_key => "_session_id",
- :cookie_only => false,
- :session_http_only=> true
- }
-end
+# Unique cookies
+config.action_controller.session = { :key => 'TracksTest' }
# Overwrite the default settings for fixtures in tests. See Fixtures
# for more details about these settings.
@@ -50,7 +39,7 @@ config.gem "flexmock"
config.gem "ZenTest", :lib => "zentest", :version => ">=4.0.0"
config.gem "hpricot"
config.gem "hoe"
-config.gem "rspec", :lib => false, :version => ">= 1.2.2"
-config.gem "rspec-rails", :lib => false, :version => ">=1.2.2"
-config.gem "webrat", :lib => false, :version => ">=0.4.3"
+config.gem 'webrat', :lib => false, :version => '>=0.7.0' unless File.directory?(File.join(Rails.root, 'vendor/plugins/webrat'))
+config.gem 'rspec', :lib => false, :version => '>=1.3.0' unless File.directory?(File.join(Rails.root, 'vendor/plugins/rspec'))
+config.gem 'rspec-rails', :lib => false, :version => '>=1.3.2' unless File.directory?(File.join(Rails.root, 'vendor/plugins/rspec-rails'))
config.gem "thoughtbot-factory_girl", :lib => "factory_girl", :source => "http://gems.github.com"
diff --git a/features/support/init_factory_girl.rb b/features/support/init_factory_girl.rb
new file mode 100644
index 00000000..2ac77c7e
--- /dev/null
+++ b/features/support/init_factory_girl.rb
@@ -0,0 +1,2 @@
+require 'factory_girl'
+Dir.glob(File.join(File.dirname(__FILE__), '../../spec/factories/*.rb')).each {|f| require f }
\ No newline at end of file
diff --git a/features/support/paths.rb b/features/support/paths.rb
index 06b3efb0..bc778a1e 100644
--- a/features/support/paths.rb
+++ b/features/support/paths.rb
@@ -9,7 +9,23 @@ module NavigationHelpers
case page_name
when /the home\s?page/
- '/'
+ root_path
+ when /the statistics page/
+ stats_path
+ when /the signup page/
+ signup_path
+ when /the login page/
+ login_path
+ when /the notes page/
+ notes_path
+ when /the contexts page/
+ contexts_path
+ when /the manage users page/
+ users_path
+ when /the repeating todos page/
+ recurring_todos_path
+ when /the integrations page/
+ integrations_path
# Add more mappings here.
# Here is an example that pulls values out of the Regexp:
diff --git a/features/support/selenium.rb b/features/support/selenium.rb
index af319c12..1d30db84 100644
--- a/features/support/selenium.rb
+++ b/features/support/selenium.rb
@@ -1,22 +1,13 @@
-Webrat.configure do |config|
- config.mode = :selenium
- config.application_environment = :selenium
- config.selenium_browser_startup_timeout = 30
- #config.selenium_server_address = "localhost"
-end
+if ENV["RAILS_ENV"] == "selenium"
+ puts "Configuring to use Selenium with Webrat for Cucumber stories"
+ Webrat.configure do |config|
+ config.mode = :selenium
+ config.application_environment = :selenium
+ config.selenium_browser_startup_timeout = 30
+ # use only if you run a separate selenium server instance and do not
+ # want webrat to start one for you
+ #config.selenium_server_address = "localhost"
+ end
-Cucumber::Rails::World.use_transactional_fixtures = false
-
-require 'database_cleaner'
-
-# clean the database once when starting
-DatabaseCleaner.clean_with :truncation
-DatabaseCleaner.strategy = :truncation
-
-Before do
- DatabaseCleaner.start
-end
-
-After do
- DatabaseCleaner.clean
-end
+ Cucumber::Rails::World.use_transactional_fixtures = false
+end
\ No newline at end of file
diff --git a/lib/tasks/cucumber-tracks.rake b/lib/tasks/cucumber-tracks.rake
new file mode 100644
index 00000000..f88b3795
--- /dev/null
+++ b/lib/tasks/cucumber-tracks.rake
@@ -0,0 +1,32 @@
+# IMPORTANT: This file is generated by cucumber-rails - edit at your own peril.
+# It is recommended to regenerate this file in the future when you upgrade to a
+# newer version of cucumber-rails. Consider adding your own code to a new file
+# instead of editing this one. Cucumber will automatically load all features/**/*.rb
+# files.
+
+vendored_cucumber_bin = Dir["#{Rails.root}/vendor/{gems,plugins}/cucumber*/bin/cucumber"].first
+$LOAD_PATH.unshift(File.dirname(vendored_cucumber_bin) + '/../lib') unless vendored_cucumber_bin.nil?
+
+begin
+ require 'cucumber/rake/task'
+
+ namespace :cucumber do
+ Cucumber::Rake::Task.new({:selenium => :env_to_selenium}, 'Run features that require selenium') do |t|
+ t.binary = vendored_cucumber_bin
+ t.fork = true # You may get faster startup if you set this to false
+ t.profile = 'selenium'
+ end
+
+ task :env_to_selenium => 'db:test:prepare' do
+ ENV['RAILS_ENV'] = 'selenium'
+ end
+
+ desc 'Run all features'
+ task :all => [:ok, :wip, :selenium]
+ end
+rescue LoadError
+ desc 'cucumber rake task not available (cucumber not installed)'
+ task :cucumber do
+ abort 'Cucumber rake task is not available. Be sure to install cucumber as a gem or plugin'
+ end
+end
\ No newline at end of file
From 7be37eabfcd66ee0dc35f8b8a879730071cf6676 Mon Sep 17 00:00:00 2001
From: Reinier Balt
Date: Tue, 27 Jul 2010 23:35:50 +0200
Subject: [PATCH 38/64] fix context scenario to match new confirm message when
deleting a context
---
features/step_definitions/context_steps.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/features/step_definitions/context_steps.rb b/features/step_definitions/context_steps.rb
index ba025d12..15864b48 100644
--- a/features/step_definitions/context_steps.rb
+++ b/features/step_definitions/context_steps.rb
@@ -36,7 +36,7 @@ When /^I delete the context "([^\"]*)"$/ do |context_name|
context = @current_user.contexts.find_by_name(context_name)
context.should_not be_nil
click_link "delete_context_#{context.id}"
- selenium.get_confirmation.should == "Are you sure that you want to delete the context '#{context_name}'?"
+ selenium.get_confirmation.should == "Are you sure that you want to delete the context '#{context_name}'? Be aware that this will also delete all actions in this context!"
wait_for do
!selenium.is_element_present("delete_context_#{context.id}")
end
From 26cd345cbef13fafa09072d453664b3aa73981ec Mon Sep 17 00:00:00 2001
From: Reinier Balt
Date: Wed, 14 Jul 2010 13:34:30 +0200
Subject: [PATCH 39/64] add form for multiple actions
---
app/views/shared/_add_new_item_form.rhtml | 42 +++++++++++++++++++++--
public/javascripts/application.js | 31 +++++++++++++----
public/stylesheets/standard.css | 2 +-
3 files changed, 65 insertions(+), 10 deletions(-)
diff --git a/app/views/shared/_add_new_item_form.rhtml b/app/views/shared/_add_new_item_form.rhtml
index 426f5806..dbd801e6 100644
--- a/app/views/shared/_add_new_item_form.rhtml
+++ b/app/views/shared/_add_new_item_form.rhtml
@@ -7,8 +7,9 @@
-%>
diff --git a/app/views/todos/create_multiple.js.rjs b/app/views/todos/create_multiple.js.rjs
new file mode 100644
index 00000000..b1c310a7
--- /dev/null
+++ b/app/views/todos/create_multiple.js.rjs
@@ -0,0 +1,42 @@
+if @saved
+ page.hide 'status'
+
+ status_message = 'Added new next action'
+ status_message += 's' if @todos.size > 1
+ status_message = 'Added new project / ' + status_message if @new_project_created
+ status_message = 'Added new context / ' + status_message if @new_context_created
+ page.notify :notice, status_message, 5.0
+
+ page['badge_count'].replace_html @down_count
+
+ # reset form and set focus to first field
+ page.send :record, "$('#todo-form-multi-new-action').clearForm();$('#todo-form-multi-new-action input:text:first').focus();"
+
+ # set defaults of form
+ page.send :record, "$('#multi_todo_context_name').val('#{@initial_context_name}');"
+ page.send :record, "$('#multi_todo_project_name').val('#{@initial_project_name}');"
+ page.send :record, "$('#multi_tag_list').val('#{@default_tags}');"
+
+ if should_show_new_item()
+ if @new_context_created
+ page.insert_html :top, 'display_box', :partial => 'contexts/context', :locals => { :context => @todo.context, :collapsible => true }
+ else
+ page.call "todoItems.ensureVisibleWithEffectAppear", "c#{@todo.context_id}" if source_view_is_one_of(:todo, :deferred, :tag)
+
+ @todos.each do |todo|
+ page.insert_html :bottom, item_container_id(todo), :partial => 'todos/todo', :locals => { :todo => todo, :parent_container_type => parent_container_type, :source_view => @source_view }
+ page.visual_effect :highlight, dom_id(todo), :duration => 3
+ end
+
+ page[empty_container_msg_div_id].hide unless empty_container_msg_div_id.nil?
+ end
+ if (source_view_is :project and @todo.pending?) or (source_view_is :deferred)
+ page['tickler-empty-nd'].hide # For some reason this does not work: page['tickler-empty-nd'].hide if (@todo.pending? or (source_view_is :deferred))
+ end
+ end
+ # make sure the behavior of the new/updated todo is enabled
+ page << "enable_rich_interaction();"
+else
+ page.show 'status'
+ page.replace_html 'status', "#{error_messages_for('todo', :object_name => 'action')}"
+end
\ No newline at end of file
diff --git a/public/javascripts/application.js b/public/javascripts/application.js
index 67d9d633..cd9e7de1 100644
--- a/public/javascripts/application.js
+++ b/public/javascripts/application.js
@@ -11,7 +11,7 @@ var TracksForm = {
toggleLink.text(hideLinkText).attr('title', hideLinkTitle);
$('#'+formId+' input:text:first').focus();
}
- toggleLink.parent.toggleClass('hide_form');
+ toggleLink.parent().toggleClass('hide_form');
},
hide_all_recurring: function () {
$.each(['daily', 'weekly', 'monthly', 'yearly'], function(){
@@ -137,8 +137,8 @@ function setup_container_toggles(){
});
}
-function askIfNewContextProvided() {
- var givenContextName = $('#todo_context_name').val();
+function askIfNewContextProvided(source) {
+ var givenContextName = $('#'+source+'todo_context_name').val();
var contextNames = [];
var contextNamesRequest = $.ajax({url: relative_to_root('contexts.autocomplete'),
async: false,
diff --git a/public/stylesheets/standard.css b/public/stylesheets/standard.css
index d588fbfe..5d604dea 100644
--- a/public/stylesheets/standard.css
+++ b/public/stylesheets/standard.css
@@ -825,7 +825,7 @@ input#go_to_project, input#context_hide {
float: right;
}
-#todo-form-new-action .submit_box, #project_form .submit_box, #context_form .submit_box, #todo-form-multi-new-acion .submit_box {
+#todo-form-new-action .submit_box, #project_form .submit_box, #context_form .submit_box, #todo-form-multi-new-action .submit_box {
height: 25px;
padding: 5px 0;
text-align: center;
From 6e5057138de7df7aa7dbe1317e22529512c06a2d Mon Sep 17 00:00:00 2001
From: Reinier Balt
Date: Wed, 14 Jul 2010 23:34:47 +0200
Subject: [PATCH 42/64] add cucumber scenarios for adding multiple next actions
---
app/helpers/todos_helper.rb | 3 +
features/shared_add_new_todo.feature | 88 +++++++++++++++++--------
features/step_definitions/todo_steps.rb | 14 ++++
3 files changed, 79 insertions(+), 26 deletions(-)
diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb
index b8ea341e..32d1bc84 100644
--- a/app/helpers/todos_helper.rb
+++ b/app/helpers/todos_helper.rb
@@ -251,11 +251,14 @@ module TodosHelper
return false if source_view_is(:context) && (@todo.project.hidden? || @todo.project.completed?)
end
+ return false if (source_view_is(:tag) && !@todo.tags.include?(@tag_name))
+
return true if source_view_is(:deferred) && @todo.deferred?
return true if source_view_is(:project) && @todo.project.hidden? && @todo.project_hidden?
return true if source_view_is(:project) && @todo.deferred?
return true if !source_view_is(:deferred) && @todo.active?
return true if source_view_is(:project) && @todo.pending?
+
return true if source_view_is(:tag) && @todo.pending?
return false
end
diff --git a/features/shared_add_new_todo.feature b/features/shared_add_new_todo.feature
index 6164469e..9955e63e 100644
--- a/features/shared_add_new_todo.feature
+++ b/features/shared_add_new_todo.feature
@@ -9,8 +9,8 @@ Feature: Add new next action from every page
| login | password | is_admin |
| testuser | secret | false |
And I have logged in as "testuser" with password "secret"
- And I have a context called "test"
- And I have a project "test" with 1 todos
+ And I have a context called "test context"
+ And I have a project "test project" with 1 todos
@selenium
Scenario Outline: I can hide the input form for single next action on a page
@@ -20,12 +20,12 @@ Feature: Add new next action from every page
Then the single action form should not be visible
Scenarios:
- | action | page |
- | go to | home page |
- | go to | tickler page |
- | visit | project page for "test"|
- | visit | context page for "test"|
- | visit | tag page for "starred" |
+ | action | page |
+ | go to | home page |
+ | go to | tickler page |
+ | visit | project page for "test project"|
+ | visit | context page for "test context"|
+ | visit | tag page for "starred" |
@selenium
Scenario Outline: I can hide the input form for multiple next actions
@@ -38,12 +38,12 @@ Feature: Add new next action from every page
And the multiple action form should not be visible
Scenarios:
- | action | page |
- | go to | home page |
- | go to | tickler page |
- | visit | project page for "test"|
- | visit | context page for "test"|
- | visit | tag page for "starred" |
+ | action | page |
+ | go to | home page |
+ | go to | tickler page |
+ | visit | project page for "test project"|
+ | visit | context page for "test context"|
+ | visit | tag page for "starred" |
@selenium
Scenario Outline: I can hide the input form and then choose both input forms
@@ -58,12 +58,12 @@ Feature: Add new next action from every page
And the multiple action form should not be visible
Scenarios:
- | action | page |
- | go to | home page |
- | go to | tickler page |
- | visit | project page for "test"|
- | visit | context page for "test"|
- | visit | tag page for "starred" |
+ | action | page |
+ | go to | home page |
+ | go to | tickler page |
+ | visit | project page for "test project"|
+ | visit | context page for "test context"|
+ | visit | tag page for "starred" |
@selenium
Scenario Outline: I can switch forms for single next action to multiple next actions
@@ -77,9 +77,45 @@ Feature: Add new next action from every page
And the multiple action form should not be visible
Scenarios:
- | action | page |
- | go to | home page |
- | go to | tickler page |
- | visit | project page for "test"|
- | visit | context page for "test"|
- | visit | tag page for "starred" |
+ | action | page |
+ | go to | home page |
+ | go to | tickler page |
+ | visit | project page for "test project"|
+ | visit | context page for "test context"|
+ | visit | tag page for "starred" |
+
+ @selenium
+ Scenario Outline: I can add a todo from several pages
+ When I the
+ And I submit a new action with description "a new next action"
+ Then I should "a new next action"
+
+ Scenarios:
+ | action | page | see |
+ | go to | home page | see |
+ | go to | tickler page | not see|
+ | visit | project page for "test project"| see |
+ | visit | context page for "test context"| see |
+ | visit | tag page for "starred" | not see|
+
+ @selenium
+ Scenario Outline: I can add multiple todos from several pages
+ When I the
+ And I follow "Add multiple next actions"
+ And I submit multiple actions with using
+ """
+ one new next action
+ another new next action
+ """
+ Then I should "one new next action"
+ And I should "another new next action"
+ And the badge should show
+ And the number of actions should be
+
+ Scenarios:
+ | action | page | see | badge | count |
+ | go to | home page | see | 3 | 3 |
+ | go to | tickler page | not see| 0 | 3 |
+ | visit | project page for "test project"| see | 3 | 3 |
+ | visit | context page for "test context"| see | 2 | 3 |
+ | visit | tag page for "starred" | not see| 0 | 3 |
\ No newline at end of file
diff --git a/features/step_definitions/todo_steps.rb b/features/step_definitions/todo_steps.rb
index 98831bca..e1b183f7 100644
--- a/features/step_definitions/todo_steps.rb
+++ b/features/step_definitions/todo_steps.rb
@@ -66,6 +66,16 @@ When /I change the (.*) field of "([^\"]*)" to "([^\"]*)"$/ do |field, todo_name
sleep(5)
end
+When /^I submit a new action with description "([^"]*)"$/ do |description|
+ fill_in "todo[description]", :with => description
+ selenium.click("xpath=//form[@id='todo-form-new-action']//button[@id='todo_new_action_submit']", :wait_for => :ajax, :javascript_framework => :jquery)
+end
+
+When /^I submit multiple actions with using$/ do |multiple_actions|
+ fill_in "todo[multiple_todos]", :with => multiple_actions
+ selenium.click("xpath=//form[@id='todo-form-multi-new-action']//button[@id='todo_multi_new_action_submit']", :wait_for => :ajax, :javascript_framework => :jquery)
+end
+
Then /^the dependencies of "(.*)" should include "(.*)"$/ do |child_name, parent_name|
parent = @current_user.todos.find_by_description(parent_name)
parent.should_not be_nil
@@ -96,3 +106,7 @@ end
Then /^I should not see the todo "([^\"]*)"$/ do |todo_description|
selenium.is_element_present("//span[.=\"#{todo_description}\"]").should be_false
end
+
+Then /^the number of actions should be (\d+)$/ do |count|
+ @current_user.todos.count.should == count.to_i
+end
From abf45246796a1797f10b6a89ad623fd0dc308527 Mon Sep 17 00:00:00 2001
From: Reinier Balt
Date: Fri, 16 Jul 2010 13:11:01 +0200
Subject: [PATCH 43/64] add validation to catch empty descriptions
---
app/controllers/todos_controller.rb | 8 +++++++-
app/views/shared/_add_new_item_form.rhtml | 2 ++
app/views/todos/create_multiple.js.rjs | 14 +++++++++++---
features/shared_add_new_todo.feature | 18 +++++++++++++++++-
features/step_definitions/todo_steps.rb | 19 +++++++++++++++++++
...todo_tag_steps.rb.rb => todo_tag_steps.rb} | 0
6 files changed, 56 insertions(+), 5 deletions(-)
rename features/step_definitions/{todo_tag_steps.rb.rb => todo_tag_steps.rb} (100%)
diff --git a/app/controllers/todos_controller.rb b/app/controllers/todos_controller.rb
index 5750ea28..da351990 100644
--- a/app/controllers/todos_controller.rb
+++ b/app/controllers/todos_controller.rb
@@ -169,7 +169,13 @@ class TodosController < ApplicationController
@projects = current_user.projects.find(:all) if @new_project_created
@initial_context_name = params['default_context_name']
@initial_project_name = params['default_project_name']
- @default_tags = @todos[0].project.default_tags unless @todos[0].project.nil?
+ if @todos.size > 0
+ @default_tags = @todos[0].project.default_tags unless @todos[0].project.nil?
+ else
+ @multiple_error = "You need to submit at least one next action"
+ @saved = false;
+ @default_tags = current_user.projects.find_by_name(@initial_project_name).default_tags unless @initial_project_name.blank?
+ end
render :action => 'create_multiple'
end
format.xml do
diff --git a/app/views/shared/_add_new_item_form.rhtml b/app/views/shared/_add_new_item_form.rhtml
index 23a98dc0..0007b72b 100644
--- a/app/views/shared/_add_new_item_form.rhtml
+++ b/app/views/shared/_add_new_item_form.rhtml
@@ -78,6 +78,8 @@
:complete => "$('#todo_multi_new_action_submit').unblock()",
:condition => "askIfNewContextProvided('multi_')") do -%>
+
+
<%= text_area( "todo", "multiple_todos", "cols" => 29, "rows" => 6, "tabindex" => 2) %>
diff --git a/app/views/todos/create_multiple.js.rjs b/app/views/todos/create_multiple.js.rjs
index b1c310a7..46146a9c 100644
--- a/app/views/todos/create_multiple.js.rjs
+++ b/app/views/todos/create_multiple.js.rjs
@@ -1,5 +1,5 @@
if @saved
- page.hide 'status'
+ page.hide 'multiple_status'
status_message = 'Added new next action'
status_message += 's' if @todos.size > 1
@@ -37,6 +37,14 @@ if @saved
# make sure the behavior of the new/updated todo is enabled
page << "enable_rich_interaction();"
else
- page.show 'status'
- page.replace_html 'status', "#{error_messages_for('todo', :object_name => 'action')}"
+ page.show 'multiple_status'
+ # add error about missing todo description that is not available in @todos
+ @multiple_error = content_tag(:div, content_tag(:p, @multiple_error), {:class => 'errorExplanation', :id => 'errorExplanation'}) unless @multiple_error.blank?
+ error_messages = @multiple_error || ""
+ # add errors of individual @todos
+ @todos.each do |todo|
+ @todo_i = todo
+ error_messages += error_messages_for('todo_i', :object_name => 'action')
+ end
+ page.replace_html 'multiple_status', error_messages
end
\ No newline at end of file
diff --git a/features/shared_add_new_todo.feature b/features/shared_add_new_todo.feature
index 9955e63e..2ad79377 100644
--- a/features/shared_add_new_todo.feature
+++ b/features/shared_add_new_todo.feature
@@ -118,4 +118,20 @@ Feature: Add new next action from every page
| go to | tickler page | not see| 0 | 3 |
| visit | project page for "test project"| see | 3 | 3 |
| visit | context page for "test context"| see | 2 | 3 |
- | visit | tag page for "starred" | not see| 0 | 3 |
\ No newline at end of file
+ | visit | tag page for "starred" | not see| 0 | 3 |
+
+ @selenium
+ Scenario: I need to fill in at least one description and a context
+ When I go to the home page
+ And I follow "Add multiple next actions"
+ And I submit the new multiple actions form with "", "", "", ""
+ Then I should see "You need to submit at least one next action"
+ When I submit the new multiple actions form with "one", "", "", ""
+ Then I should see "Context can't be blank"
+ When I fill the multiple actions form with "", "a project", "a context", "tag"
+ And I submit the new multiple actions form with
+ """
+
+
+ """
+ Then I should see "You need to submit at least one next action"
\ No newline at end of file
diff --git a/features/step_definitions/todo_steps.rb b/features/step_definitions/todo_steps.rb
index e1b183f7..d5c8020c 100644
--- a/features/step_definitions/todo_steps.rb
+++ b/features/step_definitions/todo_steps.rb
@@ -76,6 +76,25 @@ When /^I submit multiple actions with using$/ do |multiple_actions|
selenium.click("xpath=//form[@id='todo-form-multi-new-action']//button[@id='todo_multi_new_action_submit']", :wait_for => :ajax, :javascript_framework => :jquery)
end
+When /^I fill the multiple actions form with "([^"]*)", "([^"]*)", "([^"]*)", "([^"]*)"$/ do |descriptions, project_name, context_name, tags|
+ fill_in "todo[multiple_todos]", :with => descriptions
+ fill_in "multi_todo_project_name", :with => project_name
+ fill_in "multi_todo_context_name", :with => context_name
+ fill_in "multi_tag_list", :with => tags
+end
+
+When /^I submit the new multiple actions form with "([^"]*)", "([^"]*)", "([^"]*)", "([^"]*)"$/ do |descriptions, project_name, context_name, tags|
+ When "I fill the multiple actions form with \"#{descriptions}\", \"#{project_name}\", \"#{context_name}\", \"#{tags}\""
+ selenium.click("xpath=//form[@id='todo-form-multi-new-action']//button[@id='todo_multi_new_action_submit']", :wait_for => :ajax, :javascript_framework => :jquery)
+end
+
+When /^I submit the new multiple actions form with$/ do |multi_line_descriptions|
+ fill_in "todo[multiple_todos]", :with => multi_line_descriptions
+ selenium.click("xpath=//form[@id='todo-form-multi-new-action']//button[@id='todo_multi_new_action_submit']", :wait_for => :ajax, :javascript_framework => :jquery)
+end
+
+
+
Then /^the dependencies of "(.*)" should include "(.*)"$/ do |child_name, parent_name|
parent = @current_user.todos.find_by_description(parent_name)
parent.should_not be_nil
diff --git a/features/step_definitions/todo_tag_steps.rb.rb b/features/step_definitions/todo_tag_steps.rb
similarity index 100%
rename from features/step_definitions/todo_tag_steps.rb.rb
rename to features/step_definitions/todo_tag_steps.rb
From 9c82e9c974ddad86e5ae03783166ba1ee72d64d4 Mon Sep 17 00:00:00 2001
From: Reinier Balt
Date: Fri, 16 Jul 2010 14:41:04 +0200
Subject: [PATCH 44/64] DRY things up a bit
---
features/step_definitions/todo_steps.rb | 10 ++++------
features/support/world.rb | 12 ++++++++++++
2 files changed, 16 insertions(+), 6 deletions(-)
create mode 100644 features/support/world.rb
diff --git a/features/step_definitions/todo_steps.rb b/features/step_definitions/todo_steps.rb
index d5c8020c..b36a15f8 100644
--- a/features/step_definitions/todo_steps.rb
+++ b/features/step_definitions/todo_steps.rb
@@ -68,12 +68,12 @@ end
When /^I submit a new action with description "([^"]*)"$/ do |description|
fill_in "todo[description]", :with => description
- selenium.click("xpath=//form[@id='todo-form-new-action']//button[@id='todo_new_action_submit']", :wait_for => :ajax, :javascript_framework => :jquery)
+ submit_next_action_form
end
When /^I submit multiple actions with using$/ do |multiple_actions|
fill_in "todo[multiple_todos]", :with => multiple_actions
- selenium.click("xpath=//form[@id='todo-form-multi-new-action']//button[@id='todo_multi_new_action_submit']", :wait_for => :ajax, :javascript_framework => :jquery)
+ submit_multiple_next_action_form
end
When /^I fill the multiple actions form with "([^"]*)", "([^"]*)", "([^"]*)", "([^"]*)"$/ do |descriptions, project_name, context_name, tags|
@@ -85,16 +85,14 @@ end
When /^I submit the new multiple actions form with "([^"]*)", "([^"]*)", "([^"]*)", "([^"]*)"$/ do |descriptions, project_name, context_name, tags|
When "I fill the multiple actions form with \"#{descriptions}\", \"#{project_name}\", \"#{context_name}\", \"#{tags}\""
- selenium.click("xpath=//form[@id='todo-form-multi-new-action']//button[@id='todo_multi_new_action_submit']", :wait_for => :ajax, :javascript_framework => :jquery)
+ submit_multiple_next_action_form
end
When /^I submit the new multiple actions form with$/ do |multi_line_descriptions|
fill_in "todo[multiple_todos]", :with => multi_line_descriptions
- selenium.click("xpath=//form[@id='todo-form-multi-new-action']//button[@id='todo_multi_new_action_submit']", :wait_for => :ajax, :javascript_framework => :jquery)
+ submit_multiple_next_action_form
end
-
-
Then /^the dependencies of "(.*)" should include "(.*)"$/ do |child_name, parent_name|
parent = @current_user.todos.find_by_description(parent_name)
parent.should_not be_nil
diff --git a/features/support/world.rb b/features/support/world.rb
new file mode 100644
index 00000000..7bdf463a
--- /dev/null
+++ b/features/support/world.rb
@@ -0,0 +1,12 @@
+module TracksStepHelper
+ def submit_multiple_next_action_form
+ selenium.click("xpath=//form[@id='todo-form-multi-new-action']//button[@id='todo_multi_new_action_submit']", :wait_for => :ajax, :javascript_framework => :jquery)
+ end
+
+ def submit_next_action_form
+ selenium.click("xpath=//form[@id='todo-form-new-action']//button[@id='todo_new_action_submit']", :wait_for => :ajax, :javascript_framework => :jquery)
+ end
+
+end
+
+World(TracksStepHelper)
\ No newline at end of file
From 9a243b015a9a63c839cd1f409f095ed0b8570c9c Mon Sep 17 00:00:00 2001
From: Reinier Balt
Date: Wed, 28 Jul 2010 16:27:52 +0200
Subject: [PATCH 45/64] creating todos using xml/rest was broken. This fixes it
---
app/controllers/todos_controller.rb | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/app/controllers/todos_controller.rb b/app/controllers/todos_controller.rb
index da351990..425ec678 100644
--- a/app/controllers/todos_controller.rb
+++ b/app/controllers/todos_controller.rb
@@ -50,7 +50,8 @@ class TodosController < ApplicationController
@source_view = params['_source_view'] || 'todo'
@tag_name = params['_tag_name']
- unless params[:todo][:multiple_todos].nil?
+ is_multiple = params[:todo] && params[:todo][:multiple_todos] && !params[:todo][:multiple_todos].nil?
+ if is_multiple
create_multiple
else
p = TodoCreateParamsHelper.new(params, prefs)
From 3d75cd2457813f9ead43ebaa853ae0488705d0f8 Mon Sep 17 00:00:00 2001
From: Reinier Balt
Date: Thu, 29 Jul 2010 16:37:22 +0200
Subject: [PATCH 46/64] Fix #1045. The tests broke because of this fix
http://github.com/bsag/tracks/commit/cfc6d117b815c43eccdc65168e0370c23a658adc.
This exposed a new corner case that I fixed and created a test for. Also a
small refactoring.
---
app/models/recurring_todo.rb | 34 +++++++++----------------------
test/fixtures/recurring_todos.yml | 24 +++++++++++++---------
test/unit/recurring_todo_test.rb | 20 ++++++++++++++++--
3 files changed, 42 insertions(+), 36 deletions(-)
diff --git a/app/models/recurring_todo.rb b/app/models/recurring_todo.rb
index 4a916c6d..64a95889 100644
--- a/app/models/recurring_todo.rb
+++ b/app/models/recurring_todo.rb
@@ -511,30 +511,12 @@ class RecurringTodo < ActiveRecord::Base
#
# assumes self.recurring_period == 'daily'
- # determine start
- if previous.nil?
- start = self.start_from.nil? ? Time.zone.now : self.start_from
- else
- # use the next day
- start = previous + 1.day
-
- unless self.start_from.nil?
- # check if the start_from date is later than previous. If so, use
- # start_from as start to search for next date
- start = self.start_from if self.start_from > previous
- end
- end
+ start = determine_start(previous, 1.day)
if self.only_work_days
- if start.wday() >= 1 && start.wday() <= 5 # 1=monday; 5=friday
- return start
- else
- if start.wday() == 0 # sunday
- return start + 1.day
- else # saturday
- return start + 2.day
- end
- end
+ return start + 2.day if start.wday() == 6 # saturday
+ return start + 1.day if start.wday() == 0 # sunday
+ return start
else # every nth day; n = every_other1
# if there was no previous todo, do not add n: the first todo starts on
# today or on start_from
@@ -742,11 +724,15 @@ class RecurringTodo < ActiveRecord::Base
protected
- def determine_start(previous)
+ def determine_start(previous, offset=0.day)
+ # offset needs to be 1.day for daily patterns
+
if previous.nil?
start = self.start_from.nil? ? Time.zone.now : self.start_from
+ # skip to present
+ start = Time.zone.now if Time.zone.now > start
else
- start = previous
+ start = previous + offset
unless self.start_from.nil?
# check if the start_from date is later than previous. If so, use
diff --git a/test/fixtures/recurring_todos.yml b/test/fixtures/recurring_todos.yml
index 9597d674..a9bfb18c 100644
--- a/test/fixtures/recurring_todos.yml
+++ b/test/fixtures/recurring_todos.yml
@@ -1,22 +1,26 @@
-
+<%
def today
- Time.zone.now.beginning_of_day.to_s(:db)
+ Time.zone.now.beginning_of_day.to_s(:db)
end
def next_week
- 1.week.from_now.beginning_of_day.to_s(:db)
+ 1.week.from_now.beginning_of_day.to_s(:db)
end
def last_week
- 1.week.ago.beginning_of_day.to_s(:db)
+ 1.week.ago.beginning_of_day.to_s(:db)
end
def two_weeks_ago
- 2.weeks.ago.beginning_of_day.to_s(:db)
+ 2.weeks.ago.beginning_of_day.to_s(:db)
end
def two_weeks_hence
- 2.weeks.from_now.beginning_of_day.to_s(:db)
+ 2.weeks.from_now.beginning_of_day.to_s(:db)
+end
+
+def way_back
+ Time.zone.local(2008,1,1)
end
%>
@@ -29,7 +33,7 @@ call_bill_gates_every_day:
description: Call Bill Gates every day
notes: ~
state: active
- start_from: <%= last_week %>
+ start_from: <%= way_back %>
ends_on: no_end_date
end_date: ~
number_of_occurences: ~
@@ -83,7 +87,7 @@ call_bill_gates_every_week:
description: Call Bill Gates every week
notes: ~
state: active
- start_from: <%= today %>
+ start_from: <%= way_back %>
ends_on: no_end_date
end_date: ~
number_of_occurences: ~
@@ -110,7 +114,7 @@ check_with_bill_every_last_friday_of_month:
description: Check with Bill every last friday of the month
notes: ~
state: active
- start_from: <%= today %>
+ start_from: <%= way_back %>
ends_on: no_end_date
end_date: ~
number_of_occurences: ~
@@ -137,7 +141,7 @@ birthday_reinier:
description: Congratulate Reinier on his birthday
notes: ~
state: active
- start_from: <%= today %>
+ start_from: <%= way_back %>
ends_on: no_end_date
end_date: ~
number_of_occurences: ~
diff --git a/test/unit/recurring_todo_test.rb b/test/unit/recurring_todo_test.rb
index 8ae3f6da..e74b5361 100644
--- a/test/unit/recurring_todo_test.rb
+++ b/test/unit/recurring_todo_test.rb
@@ -207,11 +207,27 @@ class RecurringTodoTest < ActiveSupport::TestCase
# same month, after second wednesday
due_date = @yearly.get_due_date(Time.zone.local(2008,6,12)) # june 7th
assert_equal Time.zone.local(2009,6,10), due_date # june 10th
-
- # test handling of nil
+ end
+
+ def test_next_todo_without_previous_todo
+ # test handling of nil as previous
+ #
+ # start_from is way_back
due_date1 = @yearly.get_due_date(nil)
due_date2 = @yearly.get_due_date(Time.now.utc + 1.day)
assert_equal due_date1, due_date2
+
+ # start_from is in the future
+ @yearly.start_from = Time.now.utc + 1.week
+ due_date1 = @yearly.get_due_date(nil)
+ due_date2 = @yearly.get_due_date(Time.now.utc + 1.day)
+ assert_equal due_date1, due_date2
+
+ # start_from is nil
+ @yearly.start_from = nil
+ due_date1 = @yearly.get_due_date(nil)
+ due_date2 = @yearly.get_due_date(Time.now.utc + 1.day)
+ assert_equal due_date1, due_date2
end
def test_last_sunday_of_march
From c9be43b2c8134589c5451ba61ec82283aabe522d Mon Sep 17 00:00:00 2001
From: Reinier Balt
Date: Thu, 29 Jul 2010 18:06:30 +0200
Subject: [PATCH 47/64] add tests for #886.
---
app/views/contexts/_context_state_group.rhtml | 2 +-
features/contexts_manage.feature | 20 +++++++++++++++
features/step_definitions/context_steps.rb | 25 ++++++++++++++++++-
features/support/world.rb | 4 +++
spec/factories/factories.rb | 6 +++++
5 files changed, 55 insertions(+), 2 deletions(-)
diff --git a/app/views/contexts/_context_state_group.rhtml b/app/views/contexts/_context_state_group.rhtml
index 835d2f44..58e51cf7 100644
--- a/app/views/contexts/_context_state_group.rhtml
+++ b/app/views/contexts/_context_state_group.rhtml
@@ -1,4 +1,4 @@
-
diff --git a/features/contexts_manage.feature b/features/contexts_manage.feature
index 57002fcf..64cd4ed8 100644
--- a/features/contexts_manage.feature
+++ b/features/contexts_manage.feature
@@ -48,3 +48,23 @@ Feature: Manage contexts
And he should see that a context named "@laptop" is not present
And he should see that a context named "@ipad" is present
And the badge should show 1
+
+ @selenium, @wip
+ Scenario: Add new context
+ Given I have the following contexts
+ | name | hide |
+ | @ipad | true |
+ | @home | false |
+ When I go to the contexts page
+ And I add a new context "@phone"
+ Then I should see the context "@phone" under "active"
+
+ @selenium, @wip
+ Scenario: Add new hidden context
+ Given I have the following contexts
+ | name | hide |
+ | @ipad | true |
+ | @home | false |
+ When I go to the contexts page
+ And I add a new hidden context "@hidden"
+ Then I should see the context "@hidden" under "hidden"
diff --git a/features/step_definitions/context_steps.rb b/features/step_definitions/context_steps.rb
index 532a9f0d..671b6a70 100644
--- a/features/step_definitions/context_steps.rb
+++ b/features/step_definitions/context_steps.rb
@@ -20,6 +20,13 @@ Given /^I have a context "([^\"]*)" with (.*) actions$/ do |context_name, number
end
end
+Given /^I have the following contexts$/ do |table|
+ Context.delete_all
+ table.hashes.each do |hash|
+ context = Factory(:context, hash)
+ end
+end
+
When /^I visit the context page for "([^\"]*)"$/ do |context_name|
context = @current_user.contexts.find_by_name(context_name)
context.should_not be_nil
@@ -61,6 +68,17 @@ When /^I edit the context to rename it to "([^\"]*)"$/ do |new_name|
end
end
+When /^I add a new context "([^"]*)"$/ do |context_name|
+ fill_in "context[name]", :with => context_name
+ submit_new_context_form
+end
+
+When /^I add a new hidden context "([^"]*)"$/ do |context_name|
+ fill_in "context[name]", :with => context_name
+ check "context_hide"
+ submit_new_context_form
+end
+
Then /^I should see the context name is "([^\"]*)"$/ do |context_name|
Then "I should see \"#{context_name}\""
end
@@ -71,4 +89,9 @@ end
Then /^he should see that a context named "([^\"]*)" is not present$/ do |context_name|
Then "I should not see \"#{context_name} (\""
-end
\ No newline at end of file
+end
+
+Then /^I should see the context "([^"]*)" under "([^"]*)"$/ do |context_name, state|
+ context = Context.find_by_name(context_name)
+ response.should have_xpath("//div[@id='list-contexts-#{state}']//div[@id='context_#{context.id}']")
+end
diff --git a/features/support/world.rb b/features/support/world.rb
index 7bdf463a..20870a4a 100644
--- a/features/support/world.rb
+++ b/features/support/world.rb
@@ -7,6 +7,10 @@ module TracksStepHelper
selenium.click("xpath=//form[@id='todo-form-new-action']//button[@id='todo_new_action_submit']", :wait_for => :ajax, :javascript_framework => :jquery)
end
+ def submit_new_context_form
+ selenium.click("xpath=//form[@id='context-form']//button[@id='context_new_submit']", :wait_for => :ajax, :javascript_framework => :jquery)
+ end
+
end
World(TracksStepHelper)
\ No newline at end of file
diff --git a/spec/factories/factories.rb b/spec/factories/factories.rb
index fb344734..6a230605 100644
--- a/spec/factories/factories.rb
+++ b/spec/factories/factories.rb
@@ -3,4 +3,10 @@ Factory.define :user do |u|
u.password "secret"
u.password_confirmation { |user| user.password }
u.is_admin false
+end
+
+Factory.define :context do |c|
+ c.sequence(:name) { |n| "testcontext#{n}" }
+ c.hide false
+ c.created_at Time.now.utc
end
\ No newline at end of file
From bb23a4acba2fd6ee72ed8ac9945a1828fcd037f9 Mon Sep 17 00:00:00 2001
From: Reinier Balt
Date: Thu, 29 Jul 2010 18:08:41 +0200
Subject: [PATCH 48/64] forgot to cleanup the last patch
---
app/views/contexts/_context_state_group.rhtml | 2 +-
features/contexts_manage.feature | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/app/views/contexts/_context_state_group.rhtml b/app/views/contexts/_context_state_group.rhtml
index 58e51cf7..835d2f44 100644
--- a/app/views/contexts/_context_state_group.rhtml
+++ b/app/views/contexts/_context_state_group.rhtml
@@ -1,4 +1,4 @@
-