diff --git a/app/controllers/todos_controller.rb b/app/controllers/todos_controller.rb index cc2223b9..d7afdcc1 100644 --- a/app/controllers/todos_controller.rb +++ b/app/controllers/todos_controller.rb @@ -1303,12 +1303,20 @@ class TodosController < ApplicationController def update_due_and_show_from_dates if params["todo"].has_key?("due") - params["todo"]["due"] = parse_date_per_user_prefs(params["todo"]["due"]) + begin + params["todo"]["due"] = parse_date_per_user_prefs(params["todo"]["due"]) + rescue + @todo.errors.add_to_base("Invalid due date") + end else params["todo"]["due"] = "" end if params['todo']['show_from'] - params['todo']['show_from'] = parse_date_per_user_prefs(params['todo']['show_from']) + begin + params['todo']['show_from'] = parse_date_per_user_prefs(params['todo']['show_from']) + rescue + @todo.errors.add_to_base("Invalid show from date") + end end end @@ -1441,7 +1449,7 @@ class TodosController < ApplicationController end def tag_list - @params['tag_list'] + @params['todo_tag_list'] end def predecessor_list diff --git a/app/views/todos/_edit_form.rhtml b/app/views/todos/_edit_form.rhtml index ee95961d..9ffb3d39 100644 --- a/app/views/todos/_edit_form.rhtml +++ b/app/views/todos/_edit_form.rhtml @@ -1,7 +1,7 @@ <% todo = edit_form form_for(todo, :html=> { :name=>'todo', :id => dom_id(@todo, 'form'), :class => 'inline-form edit_todo_form' }) do |t|%> -
<%= error_messages_for("todo", :object_name => 'action') %>
+
<%= error_messages_for("todo", :object_name => 'action') %>
<%= t.hidden_field( "id" ) -%> <%= source_view_tag( @source_view ) -%> diff --git a/app/views/todos/_new_todo_form.rhtml b/app/views/todos/_new_todo_form.rhtml index 16beb13a..5e0e746c 100644 --- a/app/views/todos/_new_todo_form.rhtml +++ b/app/views/todos/_new_todo_form.rhtml @@ -22,8 +22,8 @@ - - <%= text_field_tag "tag_list", @default_tags, :size => 30, :tabindex => next_tab_index %> + + <%= text_field_tag "todo_tag_list", @default_tags, :size => 30, :tabindex => next_tab_index %> <%= content_tag("div", "", :id => "tag_list_auto_complete", :class => "auto_complete") %>
diff --git a/features/edit_a_todo.feature b/features/edit_a_todo.feature index 70b25b1e..42af3c58 100644 --- a/features/edit_a_todo.feature +++ b/features/edit_a_todo.feature @@ -30,7 +30,6 @@ Feature: Edit a next action from every page @selenium Scenario: Removing the last todo in context will hide context Given I have a todo "delete me" in the context "@home" - And I have a context called "@pc" When I go to the home page Then I should see the container for context "@home" And I should see "delete me" in the context container for "@home" @@ -156,8 +155,7 @@ Feature: Edit a next action from every page @selenium Scenario Outline: I can edit a todo to move it to another context - Given I have a context called "@pc" - And I have a context called "@laptop" + Given I have a context called "@laptop" And I have a project "my project" that has the following todos | context | description | tags | | @pc | first action | bla | @@ -175,8 +173,7 @@ Feature: Edit a next action from every page @selenium Scenario: I can edit a todo to move it to another context in tickler page - Given I have a context called "@pc" - And I have a context called "@laptop" + Given I have a context called "@laptop" And I have a project "my project" that has the following deferred todos | context | description | | @pc | first action | @@ -225,11 +222,22 @@ Feature: Edit a next action from every page When I go to the projects page Then I should see "buy mediacenter" + @selenium Scenario: I can show the notes of a todo - Given this is a pending scenario + Given I have a todo "read the notes" with notes "several things to read" + When I go to the home page + Then I should see "read the notes" + And I should not see "several things to read" + When I open the notes of "read the notes" + Then I should see "several things to read" + @selenium Scenario: I can tag a todo - Given this is a pending scenario + Given I have a todo "tag me" + When I go to the home page + And I edit the tags of "tag me" to "bla, bli" + Then I should see "bla" + And I should see "bli" Scenario: Clicking a tag of a todo will go to that tag page Given I have a todo "tag you are it" in context "@tags" with tags "taga, tagb" @@ -239,12 +247,38 @@ Feature: Edit a next action from every page When I follow "taga" Then I should be on the tag page for "taga" + @selenium Scenario: I can edit the tags of a todo - Given this is a pending scenario + Given I have a todo "tag you are it" in context "@tags" with tags "taga, tagb" + When I go to the home page + Then I should see "tag you are it" + When I edit the tags of "tag you are it" to "tagb, tagc" + Then I should not see "taga" + And I should see "tagb" + And I should see "tagc" - Scenario: Editing the context of a todo to a new context will show new context - # for home and tickler and tag - Given this is a pending scenario + @selenium + Scenario Outline: Editing the context of a todo to a new context will show new context + Given I have a todo "moving" in context "@pc" with tags "tag" + When I go to the + And I edit the context of "moving" to "@new" + And I should see the container for context "@new" + Scenarios: + | page | + | home page | + | tag page for "tag" | + + @selenium + Scenario: Editing the context of a todo in the tickler to a new context will show new context + Given I have a deferred todo "moving" in context "@pc" with tags "tag" + When I go to the tickler page + And I edit the context of "moving" to "@new" + And I should see the container for context "@new" + + @selenium Scenario: Making an error when editing a todo will show error message - Given this is a pending scenario + Given I have a todo "test" + When I go to the home page + And I try to edit the description of "test" to "" + Then I should see an error message diff --git a/features/project_edit.feature b/features/project_edit.feature index c3741c59..d98c1ecc 100644 --- a/features/project_edit.feature +++ b/features/project_edit.feature @@ -82,20 +82,38 @@ Feature: Edit a project Then I should not see "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890TOO LONG" And I should see "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456" + @selenium Scenario: Cancelling editing a project will restore project settings - Given this is a pending scenario - - Scenario: Editing the description of a todo will update todo - Given this is a pending scenario + Given I have a project called "test" + When I go to the "test" project + Then I should see "This project is active with no default context and with no default tags" + When I open the project edit form + Then I should not see "This project is active with no default context and with no default tags" + When I cancel the project edit form + Then I should see "This project is active with no default context and with no default tags" + @selenium Scenario: Moving the todo to the tickler will move todo to tickler container - Given this is a pending scenario + Given I have a project "test" with 1 todos + When I go to the "test" project + Then I should see "todo 1" in the action container + When I defer "todo 1" for 1 day + Then I should see "todo 1" in the deferred container + @selenium Scenario: Moving the todo out of the tickler will move todo to active container - Given this is a pending scenario + Given I have a project "test" with 1 todos + When I go to the "test" project + Then I should see "todo 1" in the action container + When I defer "todo 1" for 1 day + Then I should see "todo 1" in the deferred container + @selenium Scenario: Making all todos inactive will show empty message - Given this is a pending scenario # empty message is in separate container + Given I have a project "test" with 1 todos + When I go to the "test" project + And I mark "todo 1" as complete + Then I should see "Currently there are no incomplete actions in this project" # Ticket #1043 @selenium diff --git a/features/step_definitions/context_steps.rb b/features/step_definitions/context_steps.rb index dc3b9e09..c44691bd 100644 --- a/features/step_definitions/context_steps.rb +++ b/features/step_definitions/context_steps.rb @@ -6,7 +6,7 @@ end Given /^there exists an active context called "([^"]*)" for user "([^"]*)"$/ do |context_name, login| user = User.find_by_login(login) user.should_not be_nil - @context = user.contexts.create!(:name => context_name, :hide => false) + @context = user.contexts.find_or_create(:name => context_name, :hide => false) end Given /^there exists a context called "([^"]*)" for user "([^"]*)"$/ do |context_name, login| diff --git a/features/step_definitions/project_steps.rb b/features/step_definitions/project_steps.rb index 8ca46b2f..d18861fc 100644 --- a/features/step_definitions/project_steps.rb +++ b/features/step_definitions/project_steps.rb @@ -59,10 +59,32 @@ Given /^I have a hidden project called "([^"]*)"$/ do |project_name| @project.hide! end +When /^I open the project edit form$/ do + click_link "link_edit_project_#{@project.id}" + + wait_for do + selenium.is_element_present("submit_project_#{@project.id}") + end +end + +When /^I cancel the project edit form$/ do + click_link "cancel_project_#{@project.id}" + + if selenium.is_visible("submit_project_#{@project.id}") + wait_for do + !selenium.is_visible("submit_project_#{@project.id}") + end + end +end + When /^I edit the project description to "([^\"]*)"$/ do |new_description| click_link "link_edit_project_#{@project.id}" fill_in "project[description]", :with => new_description click_button "submit_project_#{@project.id}" + + wait_for do + !selenium.is_element_present("submit_project_#{@project.id}") + end end When /^I edit the project name to "([^\"]*)"$/ do |new_title| @@ -80,7 +102,7 @@ When /^I edit the project name to "([^\"]*)"$/ do |new_title| :timeout => 5 wait_for do - !selenium.is_element_present("submit_context_#{@project.id}") + !selenium.is_element_present("submit_project_#{@project.id}") end end diff --git a/features/step_definitions/todo_create_steps.rb b/features/step_definitions/todo_create_steps.rb index ea51fa65..edf02ec3 100644 --- a/features/step_definitions/todo_create_steps.rb +++ b/features/step_definitions/todo_create_steps.rb @@ -29,7 +29,7 @@ end When /^I submit a new action with description "([^"]*)" and the tags "([^"]*)" in the context "([^"]*)"$/ do |description, tags, context_name| fill_in "todo[description]", :with => description - fill_in "tag_list", :with => tags + fill_in "todo_tag_list", :with => tags # fill_in does not seem to work when the field is prefilled with something. Empty the field first clear_context_name_from_next_action_form @@ -43,7 +43,7 @@ When /^I submit a new deferred action with description "([^"]*)" and the tags "( clear_context_name_from_next_action_form fill_in "todo_context_name", :with => context_name - fill_in "tag_list", :with => tags + fill_in "todo_tag_list", :with => tags fill_in "todo[show_from]", :with => format_date(@current_user.time + 1.week) submit_next_action_form end @@ -56,7 +56,7 @@ When /^I submit a new deferred action with description "([^"]*)" to project "([^ fill_in "todo_project_name", :with => project_name fill_in "todo_context_name", :with => context_name - fill_in "tag_list", :with => tags + fill_in "todo_tag_list", :with => tags fill_in "todo[show_from]", :with => format_date(@current_user.time + 1.week) submit_next_action_form @@ -80,7 +80,7 @@ When /^I submit a new action with description "([^"]*)" to project "([^"]*)" wit fill_in "todo_project_name", :with => project_name fill_in "todo_context_name", :with => context_name - fill_in "tag_list", :with => tags + fill_in "todo_tag_list", :with => tags submit_next_action_form end diff --git a/features/step_definitions/todo_edit_steps.rb b/features/step_definitions/todo_edit_steps.rb index 18212a73..30ae79b0 100644 --- a/features/step_definitions/todo_edit_steps.rb +++ b/features/step_definitions/todo_edit_steps.rb @@ -23,6 +23,15 @@ When /^I edit the description of "([^"]*)" to "([^"]*)"$/ do |action_description submit_edit_todo_form(todo) end +When /^I try to edit the description of "([^"]*)" to "([^"]*)"$/ do |action_description, new_description| + todo = @current_user.todos.find_by_description(action_description) + todo.should_not be_nil + open_edit_form_for(todo) + fill_in "todo_description", :with => new_description + selenium.click("//div[@id='edit_todo_#{todo.id}']//button[@id='submit_todo_#{todo.id}']", :wait_for => :ajax, :javascript_framework => :jquery) + # do not wait for form to disappear to be able to test failures +end + When /^I edit the due date of "([^"]*)" to tomorrow$/ do |action_description| todo = @current_user.todos.find_by_description(action_description) todo.should_not be_nil @@ -65,6 +74,15 @@ When /^I remove the show from date from "([^"]*)"$/ do |action_description| submit_edit_todo_form(todo) end +When /^I edit the tags of "([^"]*)" to "([^"]*)"$/ do |action_description, tags| + todo = @current_user.todos.find_by_description(action_description) + todo.should_not be_nil + + open_edit_form_for(todo) + fill_in "tag_list", :with => tags + submit_edit_todo_form(todo) +end + When /^I defer "([^"]*)" for 1 day$/ do |action_description| todo = @current_user.todos.find_by_description(action_description) todo.should_not be_nil @@ -72,9 +90,7 @@ When /^I defer "([^"]*)" for 1 day$/ do |action_description| defer_todo_1day_button = "xpath=//a[@id='defer_1_todo_#{todo.id}']/img" selenium.click defer_todo_1day_button - wait_for :timeout => 5 do - !selenium.is_element_present("//div[@id='line_todo_#{todo.id}']") - end + wait_for_ajax end When /^I make a project of "([^"]*)"$/ do |action_description| @@ -89,3 +105,9 @@ When /^I make a project of "([^"]*)"$/ do |action_description| end end +Then /^I should see an error message$/ do + error_block = "xpath=//form/div[@id='edit_error_status']" + wait_for :timeout => 5 do + selenium.is_element_present(error_block) + end +end diff --git a/features/step_definitions/todo_steps.rb b/features/step_definitions/todo_steps.rb index fe61dbda..650d60d5 100644 --- a/features/step_definitions/todo_steps.rb +++ b/features/step_definitions/todo_steps.rb @@ -40,12 +40,34 @@ Given /^I have a todo "([^"]*)"$/ do |description| Given "I have a todo \"#{description}\" in the context \"Context A\"" end +Given /^I have a todo "([^"]*)" with notes "([^"]*)"$/ do |description, notes| + Given "I have a todo \"#{description}\" in the context \"Context A\"" + @todo.notes = notes + @todo.save! +end + Given /^I have ([0-9]+) todos$/ do |count| count.to_i.downto 1 do |i| Given "I have a todo \"todo #{i}\" in the context \"Context A\"" end end +Given /^I have a todo with description "([^"]*)" in project "([^"]*)" with tags "([^"]*)" in the context "([^"]*)"$/ do |action_description, project_name, tags, context_name| + context = @current_user.contexts.find_or_create(:name => context_name) + project = @current_user.projects.find_or_create(:name => project_name) + @todo = @current_user.todos.create!(:context_id => context.id, :project_id => project.id, :description => action_description) + @todo.tag_with(tags) + @todo.save +end + +Given /^I have a todo with description "([^"]*)" in project "([^"]*)" with tags "([^"]*)" in the context "([^"]*)" that is due next week$/ do |action_description, project_name, tags, context_name| + Given "I have a todo with description \"#{action_description}\" in project \"#{project_name}\" with tags \"#{tags}\" in the context \"#{context_name}\"" + @todo.due = @current_user.time + 1.week + @todo.save! +end + +###### DEFERRED TODOS ####### + Given /^I have ([0-9]+) deferred todos$/ do |count| context = @current_user.contexts.create!(:name => "context B") count.to_i.downto 1 do |i| @@ -66,6 +88,14 @@ Given /^I have a deferred todo "([^"]*)"$/ do |description| Given "I have a deferred todo \"#{description}\" in the context \"context B\"" end +Given /^I have a deferred todo "([^"]*)" in context "([^"]*)" with tags "([^"]*)"$/ do |action_description, context_name, tag_list| + Given "I have a todo \"#{action_description}\" in context \"#{context_name}\" with tags \"#{tag_list}\"" + @todo.show_from = @current_user.time + 1.week + @todo.save! +end + +####### COMPLETED TODOS ####### + Given /^I have ([0-9]+) completed todos in project "([^"]*)" in context "([^"]*)"$/ do |count, project_name, context_name| @context = @current_user.contexts.find_by_name(context_name) @context.should_not be_nil @@ -117,25 +147,13 @@ Given /^I have ([0-9]+) completed todos with a note in project "([^"]*)" in cont @todos.each { |t| t.notes = "note #{t.id}"; t.save! } end -Given /^I have a todo with description "([^"]*)" in project "([^"]*)" with tags "([^"]*)" in the context "([^"]*)"$/ do |action_description, project_name, tags, context_name| - context = @current_user.contexts.find_or_create(:name => context_name) - project = @current_user.projects.find_or_create(:name => project_name) - @todo = @current_user.todos.create!(:context_id => context.id, :project_id => project.id, :description => action_description) - @todo.tag_with(tags) - @todo.save -end - -Given /^I have a todo with description "([^"]*)" in project "([^"]*)" with tags "([^"]*)" in the context "([^"]*)" that is due next week$/ do |action_description, project_name, tags, context_name| - Given "I have a todo with description \"#{action_description}\" in project \"#{project_name}\" with tags \"#{tags}\" in the context \"#{context_name}\"" - @todo.due = @current_user.time + 1.week - @todo.save! -end - Given /^I have a completed todo with description "([^"]*)" in project "([^"]*)" with tags "([^"]*)" in the context "([^"]*)"$/ do |action_description, project_name, tags, context_name| Given "I have a todo with description \"#{action_description}\" in project \"#{project_name}\" with tags \"#{tags}\" in the context \"#{context_name}\"" @todo.complete! end +####### PROJECT WITH TODOS ###### + Given /^I have a project "([^"]*)" that has the following todos$/ do |project_name, todos| Given "I have a project called \"#{project_name}\"" @project.should_not be_nil @@ -273,7 +291,6 @@ Then /^I should see an unstarred "([^"]*)"$/ do |action_description| end end - When /^I delete the action "([^"]*)"$/ do |action_description| todo = @current_user.todos.find_by_description(action_description) todo.should_not be_nil @@ -291,6 +308,18 @@ When /^I delete the todo "([^"]*)"$/ do |action_description| When "I delete the action \"#{action_description}\"" end +When /^I open the notes of "([^"]*)"$/ do |action_description| + todo = @current_user.todos.find_by_description(action_description) + todo.should_not be_nil + + show_notes_img = "xpath=//div[@id='line_todo_#{todo.id}']/div/a/img" + selenium.click show_notes_img + + wait_for :timeout => 5 do + selenium.is_visible "//div[@id='notes_todo_#{todo.id}']" + end +end + Then /^I should see ([0-9]+) todos$/ do |count| count.to_i.downto 1 do |i| match_xpath "div[" diff --git a/features/tagging_todos.feature b/features/tagging_todos.feature index 2ab5a72e..d958f6cd 100644 --- a/features/tagging_todos.feature +++ b/features/tagging_todos.feature @@ -9,15 +9,6 @@ Feature: Tagging todos | testuser | secret | false | And I have logged in as "testuser" with password "secret" - Scenario: I can edit a todo to add tags to that todo - Given this is a pending scenario - - Scenario: I can add a new todo with tags - Given this is a pending scenario - - Scenario: I can show all todos tagged with a specific tag - Given this is a pending scenario - Scenario: I can remove a tag from a todo from the tag view and the tag will be removed Given this is a pending scenario @@ -27,14 +18,8 @@ Feature: Tagging todos Scenario: I can add a new todo from tag view with a different tag and it will not be added to the page Given this is a pending scenario - Scenario: I can change the context of a tagged todo in tag view and it will move the tag on the page - Given this is a pending scenario - - Scenario: I can defer a tagged todo in tag view and it will move the todo on the page to the deferred container - Given this is a pending scenario - Scenario: I can move a tagged todo in tag view to a hidden project and it will move the todo on the page to the hidden container Given this is a pending scenario -Scenario: I can move a tagged todo in tag view to a hidden context and it will move the todo on the page to the hidden container + Scenario: I can move a tagged todo in tag view to a hidden context and it will move the todo on the page to the hidden container Given this is a pending scenario diff --git a/public/javascripts/application.js b/public/javascripts/application.js index 48b0076a..71ba9e5e 100644 --- a/public/javascripts/application.js +++ b/public/javascripts/application.js @@ -12,7 +12,7 @@ var TracksForm = { $('#'+formId+' input:text:first').focus(); } toggleLink.parent().toggleClass('hide_form'); - }, + }, set_project_name: function (name) { $('input#todo_project_name').val(name); }, @@ -35,7 +35,7 @@ var TracksForm = { $('#project_name').html(name); }, set_tag_list: function (name) { - $('input#tag_list').val(name); + $('input#todo_tag_list').val(name); }, set_tag_list_for_multi_add: function (name) { $('#multi_tag_list').val(name); @@ -80,7 +80,7 @@ var TracksForm = { /* submit todo form after entering new todo */ $("button#todo_new_action_submit").live('click', function (ev) { - if ($('input#predecessor_input').val() != "") + if ($('input#predecessor_input').val() != "") if (!confirm(i18n['todos.unresolved_dependency'])) return false; if (TodoItems.askIfNewContextProvided('', this)) @@ -181,12 +181,12 @@ var TracksPages = { var flash = $('div#message_holder'); flash.html("

"+message+"

"); flash = $('h4#flash'); - + fadein_duration = 1500; fadeout_duration = 1500; show_duration = fade_duration_in_sec*1000 - fadein_duration - fadeout_duration if (show_duration < 0) - show_duration = 1000; + show_duration = 1000; flash.fadeIn(fadein_duration).delay(show_duration).fadeOut(fadeout_duration); }, set_page_badge: function(count) { @@ -251,7 +251,8 @@ var TracksPages = { ProjectItems.setup_autocomplete_for_projects('input[name=project_name]'); ContextItems.setup_autocomplete_for_contexts('input[name=context_name]'); ContextItems.setup_autocomplete_for_contexts('input[id="project_default_context_name"]'); - TracksPages.setup_autocomplete_for_tag_list('input[name=tag_list]'); + TracksPages.setup_autocomplete_for_tag_list('input[name=tag_list]'); // todo edit form + TracksPages.setup_autocomplete_for_tag_list('input[name=todo_tag_list]'); // new todo form TracksPages.setup_autocomplete_for_tag_list('input[id="project_default_tags"]'); TodoItems.setup_autocomplete_for_predecessor(); },