Merge branch 'master' into new-gui

Conflicts:
	Gemfile.lock
	app/assets/javascripts/application.js
	app/helpers/todos_helper.rb
	app/views/shared/_footer.html.erb
This commit is contained in:
Reinier Balt 2014-06-26 10:46:20 +02:00
commit 59291f305f
170 changed files with 629 additions and 882 deletions

1
.gitignore vendored
View file

@ -11,7 +11,6 @@
/.bundle
/.emacs-project
/.redcar
/bin
/coverage
/db/*.db
/db/*.sqlite3

View file

@ -8,16 +8,18 @@ rvm:
bundler_args: --without development
before_install:
before_install:
- "gem install bundler -v=1.5.1"
- "mysql -e 'create database tracks_test;'"
- "export DISPLAY=:99.0"
- "sh -e /etc/init.d/xvfb start"
- "cp config/site.yml.tmpl config/site.yml"
- "cp config/database.yml.tmpl config/database.yml"
script: "CODECLIMATE_REPO_TOKEN=5c52fdd2bbcd0734d56ddb2c3cbaac782da345273e8689d25f54a065ccc3397c bundle exec rake ci RACK_ENV=test"
script: "bin/rake ci"
notifications:
email: false
addons:
code_climate:
repo_token:
secure: Ev0v5x9abxM+vlCdY7J/AHMP/Eq9FlhFtNlKSMnD3n2I1xWT0oB5kgidS3L+U0/janXxf4aNe28rDcj5AUePSoNBiSg6wzZ95D3Dz7AxqL9i61IQ/hllpA1kzQrTUsXtS5qAqa3H90Ev5hTQQahExjGvLB+1t8Ea2JBLR+8nUvU=

20
Gemfile
View file

@ -1,13 +1,13 @@
source 'https://rubygems.org'
gem 'rails', '~>4.0.0'
gem 'sass-rails', '~>4.0.0'
gem 'coffee-rails', '~>4.0.0'
gem 'rails', '~>4.1.0'
gem 'sass-rails', '~>4.0'
gem 'coffee-rails', '~>4.0'
gem 'json'
#gem 'json'
# todo: remove xml api
gem 'actionpack-xml_parser', git: 'https://github.com/rails/actionpack-xml_parser'
gem 'actionpack-xml_parser', '>=1.0.1'
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
gem 'therubyracer'
@ -38,10 +38,9 @@ gem "htmlentities"
gem "swf_fu"
gem "rails_autolink"
gem "cache_digests"
gem "highline" # for reset_password rake task
# To use ActiveModel has_secure_password
gem 'bcrypt-ruby', '~> 3.0.0'
gem 'bcrypt', '~> 3.1.7'
# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
gem 'turbolinks'
@ -50,8 +49,10 @@ gem 'turbolinks'
# gem 'jbuilder', '~> 1.2'
group :development do
gem "spring"
gem "spring-commands-cucumber"
gem "yard"
gem "tolk", git: 'https://github.com/tolk/tolk'
gem 'tolk', '>=1.5.0'
gem "bullet"
gem "rack-mini-profiler"
end
@ -64,8 +65,7 @@ group :test do
gem "database_cleaner"
gem "mocha", :require => false
gem "aruba", git: 'https://github.com/cucumber/aruba', :require => false # need 0.5.4 for piping files; 0.5.3 is latest
gem "timecop", "~> 0.6.2"
gem "aruba", ">=0.5.4", :require => false
# Note that > 2.14 has problems, see:
# https://code.google.com/p/selenium/issues/detail?id=3075

View file

@ -1,262 +0,0 @@
GIT
remote: https://github.com/cucumber/aruba
revision: fccb412d18d699b7ecacd0da6b2e5338987cf4eb
specs:
aruba (0.5.4)
childprocess (>= 0.3.6)
cucumber (>= 1.1.1)
rspec-expectations (>= 2.7.0)
GIT
remote: https://github.com/rails/actionpack-xml_parser
revision: e1516064761ea26502cd79b283f6af0fa2b1edf5
specs:
actionpack-xml_parser (1.0.1)
actionpack (>= 4.0.0, < 5)
GIT
remote: https://github.com/tolk/tolk
revision: 06f99b3b747f2f8f7297fa35ec9c9d5f38eaada6
specs:
tolk (1.4.00)
safe_yaml (~> 0.8)
will_paginate
GEM
remote: https://rubygems.org/
specs:
RedCloth (4.2.9)
aasm (3.1.1)
actionmailer (4.0.4)
actionpack (= 4.0.4)
mail (~> 2.5.4)
actionpack (4.0.4)
activesupport (= 4.0.4)
builder (~> 3.1.0)
erubis (~> 2.7.0)
rack (~> 1.5.2)
rack-test (~> 0.6.2)
activemodel (4.0.4)
activesupport (= 4.0.4)
builder (~> 3.1.0)
activerecord (4.0.4)
activemodel (= 4.0.4)
activerecord-deprecated_finders (~> 1.0.2)
activesupport (= 4.0.4)
arel (~> 4.0.0)
activerecord-deprecated_finders (1.0.3)
activesupport (4.0.4)
i18n (~> 0.6, >= 0.6.9)
minitest (~> 4.2)
multi_json (~> 1.3)
thread_safe (~> 0.1)
tzinfo (~> 0.3.37)
acts_as_list (0.4.0)
activerecord (>= 3.0)
arel (4.0.2)
atomic (1.1.16)
bcrypt-ruby (3.0.1)
bootstrap-sass (3.1.1.0)
sass (~> 3.2)
builder (3.1.4)
bullet (4.8.0)
activesupport
uniform_notifier (>= 1.4.0)
cache_digests (0.3.1)
actionpack (>= 3.2)
thread_safe
capybara (2.2.1)
mime-types (>= 1.16)
nokogiri (>= 1.3.3)
rack (>= 1.0.0)
rack-test (>= 0.5.4)
xpath (~> 2.0)
childprocess (0.5.2)
ffi (~> 1.0, >= 1.0.11)
codeclimate-test-reporter (0.3.0)
simplecov (>= 0.7.1, < 1.0.0)
coffee-rails (4.0.1)
coffee-script (>= 2.2.0)
railties (>= 4.0.0, < 5.0)
coffee-script (2.2.0)
coffee-script-source
execjs
coffee-script-source (1.7.0)
cucumber (1.3.14)
builder (>= 2.1.2)
diff-lcs (>= 1.1.3)
gherkin (~> 2.12)
multi_json (>= 1.7.5, < 2.0)
multi_test (>= 0.1.1)
cucumber-rails (1.4.0)
capybara (>= 1.1.2)
cucumber (>= 1.2.0)
nokogiri (>= 1.5.0)
rails (>= 3.0.0)
database_cleaner (1.2.0)
diff-lcs (1.2.5)
docile (1.1.3)
erubis (2.7.0)
execjs (2.0.2)
factory_girl (4.4.0)
activesupport (>= 3.0.0)
factory_girl_rails (4.4.1)
factory_girl (~> 4.4.0)
railties (>= 3.0.0)
ffi (1.9.3)
font-awesome-sass (4.0.3.1)
sass (~> 3.2)
gherkin (2.12.2)
multi_json (~> 1.3)
highline (1.6.21)
hike (1.2.3)
htmlentities (4.3.1)
i18n (0.6.9)
jquery-rails (3.1.0)
railties (>= 3.0, < 5.0)
thor (>= 0.14, < 2.0)
json (1.8.1)
libv8 (3.16.14.3)
mail (2.5.4)
mime-types (~> 1.16)
treetop (~> 1.4.8)
metaclass (0.0.4)
mime-types (1.25.1)
mini_portile (0.5.3)
minitest (4.7.5)
mocha (1.0.0)
metaclass (~> 0.0.1)
mousetrap-rails (1.4.6)
multi_json (1.9.2)
multi_test (0.1.1)
mysql2 (0.3.15)
nokogiri (1.6.1)
mini_portile (~> 0.5.0)
polyglot (0.3.4)
rack (1.5.2)
rack-mini-profiler (0.9.1)
rack (>= 1.1.3)
rack-test (0.6.2)
rack (>= 1.0)
rails (4.0.4)
actionmailer (= 4.0.4)
actionpack (= 4.0.4)
activerecord (= 4.0.4)
activesupport (= 4.0.4)
bundler (>= 1.3.0, < 2.0)
railties (= 4.0.4)
sprockets-rails (~> 2.0.0)
rails_autolink (1.1.5)
rails (> 3.1)
railties (4.0.4)
actionpack (= 4.0.4)
activesupport (= 4.0.4)
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
rake (10.2.2)
ref (1.0.5)
rspec-expectations (2.14.5)
diff-lcs (>= 1.1.3, < 2.0)
rubyzip (1.1.2)
safe_yaml (0.9.7)
sanitize (2.1.0)
nokogiri (>= 1.4.4)
sass (3.2.18)
sass-rails (4.0.2)
railties (>= 4.0.0, < 5.0)
sass (~> 3.2.0)
sprockets (~> 2.8, <= 2.11.0)
sprockets-rails (~> 2.0.0)
selenium-webdriver (2.40.0)
childprocess (>= 0.5.0)
multi_json (~> 1.0)
rubyzip (~> 1.0)
websocket (~> 1.0.4)
simplecov (0.8.2)
docile (~> 1.1.0)
multi_json
simplecov-html (~> 0.8.0)
simplecov-html (0.8.0)
sprockets (2.11.0)
hike (~> 1.2)
multi_json (~> 1.0)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
sprockets-rails (2.0.1)
actionpack (>= 3.0)
activesupport (>= 3.0)
sprockets (~> 2.8)
sqlite3 (1.3.9)
swf_fu (2.0.4)
coffee-script
rails (>= 3.1)
therubyracer (0.12.1)
libv8 (~> 3.16.14.0)
ref
thor (0.19.1)
thread_safe (0.3.1)
atomic (>= 1.1.7, < 2)
tilt (1.4.1)
timecop (0.6.3)
treetop (1.4.15)
polyglot
polyglot (>= 0.3.1)
turbolinks (2.2.1)
coffee-rails
tzinfo (0.3.39)
uglifier (2.5.0)
execjs (>= 0.3.0)
json (>= 1.8.0)
uniform_notifier (1.4.0)
websocket (1.0.7)
will_paginate (3.0.5)
will_paginate-bootstrap (1.0.0)
will_paginate (>= 3.0.3)
xpath (2.0.0)
nokogiri (~> 1.3)
yard (0.8.7.4)
PLATFORMS
ruby
DEPENDENCIES
RedCloth
aasm
actionpack-xml_parser!
acts_as_list
aruba!
bcrypt-ruby (~> 3.0.0)
bootstrap-sass
bullet
cache_digests
capybara
codeclimate-test-reporter
coffee-rails (~> 4.0.0)
cucumber-rails
database_cleaner
factory_girl_rails
font-awesome-sass
highline
htmlentities
jquery-rails
json
mocha
mousetrap-rails
mysql2
rack-mini-profiler
rails (~> 4.0.0)
rails_autolink
rspec-expectations
sanitize
sass-rails (~> 4.0.0)
selenium-webdriver
simplecov
sqlite3
swf_fu
therubyracer
timecop (~> 0.6.2)
tolk!
turbolinks
uglifier (>= 1.3.0)
will_paginate-bootstrap
yard

View file

@ -1,5 +1,5 @@
# Tracks: a GTD(TM) web application, built with Ruby on Rails
Copyright (C) 2004-2013 rousette.org.uk
Copyright (C) 2004-2014 rousette.org.uk
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@ -9,9 +9,8 @@ of the License, or (at your option) any later version.
* Project homepage: http://getontracks.org/
* Manual: http://getontracks.org/manual/
* Source at GitHub: https://github.com/TracksApp/tracks
* Assembla space (for bug reports and feature requests): https://www.assembla.com/spaces/tracks-tickets/tickets
* Bug reports and feature requests: https://github.com/TracksApp/tracks/issues
* Wiki (community contributed information): https://github.com/TracksApp/tracks/wiki
* Forum (read-only): http://getontracks.org/forums/
* Mailing list: http://groups.google.com/group/TracksApp
* Original developer: bsag (http://www.rousette.org.uk/)
* Contributors: https://github.com/TracksApp/tracks/wiki/Contributors
@ -19,6 +18,7 @@ of the License, or (at your option) any later version.
[![Build Status](https://travis-ci.org/TracksApp/tracks.png?branch=master)](https://travis-ci.org/TracksApp/tracks)
[![Code Climate](https://codeclimate.com/github/TracksApp/tracks.png)](https://codeclimate.com/github/TracksApp/tracks)
[![Dependency Status](https://gemnasium.com/TracksApp/tracks.svg)](https://gemnasium.com/TracksApp/tracks)
Full instructions for both new installations and upgrades from older installations of Tracks
can be found within the /doc directory.
@ -29,7 +29,7 @@ different configurations which can be used (e.g. running Tracks on your local
computer or on a remote server). If you choose the appropriate section for your
situation (installation vs. upgrade), and use the easiest (recommended) method,
you should find the instructions easy to follow. If you encounter problems, try
searching the wiki, forum or mailing list (URLs above), and ask a question if
searching the wiki or mailing list (URLs above), and ask a question if
you cannot find a solution to your problem.
The wiki has a lot of user contributed installation HOWTOs for various webhosts, specific OS's and more.

View file

@ -3,4 +3,4 @@
require File.expand_path('../config/application', __FILE__)
Tracksapp::Application.load_tasks
Rails.application.load_tasks

BIN
app/assets/images/next.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 575 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 573 B

View file

@ -12,9 +12,7 @@
//
//= require jquery
//= require jquery_ujs
//
//= require bootstrap
//
//= require mousetrap
//
// Stuff in vendor/assets
@ -32,4 +30,5 @@
//
// Stuff in app/assets
//= require tracks.js
//= require keybindings.js
//= require disable_fx_in_test
//= require keybindings.js

View file

@ -0,0 +1,3 @@
<% if Rails.env.test? || Rails.env.cucumber? %>
$.fx.off = true;
<% end %>

View file

@ -588,7 +588,7 @@ var TodoItems = {
$(document).on("click",'.item-container a.delete_dependency_button', function(evt){
var predecessor_id=$(this).attr("x_predecessors_id");
var ajax_options = default_ajax_options_for_scripts('DELETE', this.href, $(this).parents('.item-container'));
ajax_options.data << {predecessor: predecessor_id}
ajax_options.data["predecessor"] = predecessor_id
$.ajax(ajax_options);
return false;
});
@ -1245,7 +1245,7 @@ function setup_periodic_check(url_for_check, interval_in_sec, method) {
function(){
var settings = default_ajax_options_for_scripts( method ? method : "GET", url_for_check, null);
if(typeof(AUTH_TOKEN) != 'undefined'){
settings.data << {authenticity_token: AUTH_TOKEN}
settings.data["authenticity_token"] = AUTH_TOKEN
}
$.ajax(settings);
},

View file

@ -13,6 +13,9 @@ class CalendarController < ApplicationController
respond_to do |format|
format.html
format.m {
cookies[:mobile_url]= {:value => request.fullpath, :secure => SITE_CONFIG['secure_cookies']}
}
format.ics {
render :action => 'show', :layout => false, :content_type => Mime::ICS
}

View file

@ -25,7 +25,7 @@ class MailgunController < ApplicationController
def verify
unless params['signature'] == OpenSSL::HMAC.hexdigest(
OpenSSL::Digest::Digest.new('sha256'),
OpenSSL::Digest.new('sha256'),
SITE_CONFIG['mailgun_api_key'],
'%s%s' % [params['timestamp'], params['token']]
)

View file

@ -70,6 +70,7 @@ class RecurringTodosController < ApplicationController
@down_count = current_user.recurring_todos.active.count
@new_recurring_todo = RecurringTodo.new
else
@recurring_todo = builder.recurring_todo
@status_message = t('todos.error_saving_recurring')
end

View file

@ -34,8 +34,8 @@ class StatsController < ApplicationController
@interpolated_actions_created_this_month = interpolate_avg_for_current_month(@actions_created_last12months_array)
@interpolated_actions_done_this_month = interpolate_avg_for_current_month(@actions_done_last12months_array)
@created_count_array = Array.new(13, actions_last12months.created_after(@cut_off_year).count/12.0)
@done_count_array = Array.new(13, actions_last12months.completed_after(@cut_off_year).count/12.0)
@created_count_array = Array.new(13, actions_last12months.created_after(@cut_off_year).count(:all)/12.0)
@done_count_array = Array.new(13, actions_last12months.completed_after(@cut_off_year).count(:all)/12.0)
render :layout => false
end
@ -110,7 +110,7 @@ class StatsController < ApplicationController
@max_actions = @actions_completion_time_array.max
# get percentage done cumulative
@cum_percent_done = convert_to_cumulative_array(@actions_completion_time_array, @actions_completion_time.count)
@cum_percent_done = convert_to_cumulative_array(@actions_completion_time_array, @actions_completion_time.count(:all))
render :layout => false
end

View file

@ -49,7 +49,10 @@ class TodosController < ApplicationController
headers['Content-Type']=Mime::TEXT.to_s
render :content_type => Mime::TEXT
end
format.xml { render :xml => @todos.to_xml( *todo_xml_params ) }
format.xml do
@xml_todos = params[:limit_to_active_todos] ? @not_done_todos : @todos
render :xml => @xml_todos.to_xml( *todo_xml_params )
end
format.any(:rss, :atom) { @feed_title, @feed_description = 'Tracks Actions', "Actions for #{current_user.display_name}" }
format.ics
end

View file

@ -21,7 +21,7 @@ module ApplicationHelper
end
def days_from_today(date)
(date.in_time_zone.to_date - UserTime.new(current_user).date).to_i
(date.in_time_zone.to_date - Date.current).to_i
end
# Check due date in comparison to today's date Flag up date appropriately with

0
app/helpers/stats_helper.rb Executable file → Normal file
View file

View file

@ -228,7 +228,7 @@ module TodosHelper
def remote_toggle_checkbox(todo=@todo)
check_box_tag("mark_complete_#{todo.id}", toggle_check_todo_path(todo), todo.completed?, :class => 'item-checkbox',
:title => todo.pending? ? t('todos.blocked_by', :predecessors => todo.uncompleted_predecessors.map(&:description).join(', ')) : "", :readonly => todo.pending?)
:title => todo.pending? ? t('todos.blocked_by', :predecessors => todo.uncompleted_predecessors.to_a.map(&:description).join(', ')) : "", :readonly => todo.pending?)
end
def remote_mobile_checkbox(todo=@todo)
@ -241,8 +241,8 @@ module TodosHelper
if todo.completed?
content_tag(:span, {class: "label"}) { format_date( todo.completed_at ) }
elsif todo.pending?
title = t('todos.depends_on')+ ": " + todo.uncompleted_predecessors.map(&:description).join(', ')
content_tag(:a, {:title => title}) { content_tag(:span, {class: "label label-info"}) { t('todos.pending') } }
title = t('todos.depends_on')+ ": " + todo.uncompleted_predecessors.to_a.map(&:description).join(', ')
content_tag(:a, {:title => title}) { content_tag(:span, {:class => :orange}) { t('todos.pending') } }
elsif todo.deferred?
show_date( todo.show_from )
else
@ -253,7 +253,7 @@ module TodosHelper
def successors_span(todo=@todo)
unless todo.pending_successors.empty?
pending_count = todo.pending_successors.count
title = "#{t('todos.has_x_pending', :count => pending_count)}: #{todo.pending_successors.map(&:description).join(', ')}"
title = "#{t('todos.has_x_pending', :count => pending_count)}: #{todo.pending_successors.to_a.map(&:description).join(', ')}"
image_tag( 'successor_off.png', :width=>'10', :height=>'16', :border=>'0', :title => title )
end
end
@ -267,7 +267,7 @@ module TodosHelper
end
def tag_list_text(todo=@todo)
todo.tags.join(', ')
todo.tags.to_a.join(', ')
end
def tag_span (tag, mobile=false)
@ -498,7 +498,14 @@ module TodosHelper
end
def todo_moved_out_of_container
return (@project_changed && @group_view_by=='project') || (@context_changed && @group_view_by=='context')
# moved from one project container to another
moved_project = @project_changed && @group_view_by=='project'
# moved from one context container to another
moved_context = @context_changed && @group_view_by=='context'
# moved from actions-without-project container to another
moved_without_project = @context_changed && @group_view_by=='project' && @todo.project_id.nil?
return moved_project || moved_context || moved_without_project
end
def update_needs_to_hide_container

View file

@ -15,13 +15,13 @@ class Preference < ActiveRecord::Base
date = nil
if s.is_a?(Time)
date = s.in_time_zone(time_zone).to_date
date = s.to_date
elsif s.is_a?(String)
date = Date.strptime(s, date_format)
else
raise ArgumentError.new("Bad argument type:#{s.class}")
end
UserTime.new(user).midnight(date)
date.in_time_zone(time_zone).beginning_of_day
end
end

View file

@ -101,9 +101,8 @@ class Project < ActiveRecord::Base
end
def needs_review?(user)
current_time = UserTime.new(user).time
return active? && ( last_reviewed.nil? ||
(last_reviewed < current_time - user.prefs.review_period.days))
(last_reviewed < Time.current - user.prefs.review_period.days))
end
def blocked?
@ -175,4 +174,8 @@ class NullProject
""
end
def persisted?
false
end
end

View file

@ -1,6 +1,7 @@
module RecurringTodos
class MonthlyRecurringTodosBuilder < AbstractRecurringTodosBuilder
attr_reader :recurring_todo
def initialize(user, attributes)
super(user, attributes, MonthlyRepeatPattern)
@ -42,4 +43,4 @@ module RecurringTodos
end
end
end

View file

@ -1,6 +1,7 @@
module RecurringTodos
class WeeklyRecurringTodosBuilder < AbstractRecurringTodosBuilder
attr_reader :recurring_todo
def initialize(user, attributes)
super(user, attributes, WeeklyRepeatPattern)
@ -39,4 +40,4 @@ module RecurringTodos
end
end
end

View file

@ -1,6 +1,7 @@
module RecurringTodos
class YearlyRecurringTodosBuilder < AbstractRecurringTodosBuilder
attr_reader :recurring_todo
def initialize(user, attributes)
super(user, attributes, YearlyRepeatPattern)
@ -41,4 +42,4 @@ module RecurringTodos
end
end
end

View file

@ -207,6 +207,7 @@ class Todo < ActiveRecord::Base
def remove_predecessor(predecessor)
self.predecessors.delete(predecessor)
if self.predecessors.empty?
self.reload # reload predecessors
self.not_part_of_hidden_container? ? self.activate! : self.hide!
else
save!
@ -263,7 +264,7 @@ class Todo < ActiveRecord::Base
activate
else
# parse Date objects into the proper timezone
date = UserTime.new(user).midnight(date) if (date.is_a? Date)
date = date.in_time_zone.beginning_of_day if (date.is_a? Date)
# show_from needs to be set before state_change because of "bug" in aasm.
# If show_from is not set, the todo will not validate and thus aasm will not save

View file

@ -56,13 +56,13 @@ class User < ActiveRecord::Base
end
def alphabetize(scope_conditions = {})
projects = where(scope_conditions)
projects.sort!{ |x,y| x.name.downcase <=> y.name.downcase }
projects.to_a.sort!{ |x,y| x.name.downcase <=> y.name.downcase }
self.update_positions(projects.map{ |p| p.id })
return projects
end
def actionize(scope_conditions = {})
todos_in_project = where(scope_conditions).includes(:todos)
todos_in_project.sort!{ |x, y| -(x.todos.active.count <=> y.todos.active.count) }
todos_in_project.to_a.sort!{ |x, y| -(x.todos.active.count <=> y.todos.active.count) }
todos_in_project.reject{ |p| p.todos.active.count > 0 }
sorted_project_ids = todos_in_project.map {|p| p.id}
@ -90,7 +90,7 @@ class User < ActiveRecord::Base
order('show_from ASC, todos.created_at DESC')},
:class_name => 'Todo') do
def find_and_activate_ready
where('show_from <= ?', Time.zone.now).collect { |t| t.activate! }
where('show_from <= ?', Time.current).collect { |t| t.activate! }
end
end
@ -160,7 +160,7 @@ class User < ActiveRecord::Base
end
def date
UserTime.new(self).midnight(Time.now)
Date.current
end
def generate_token

View file

@ -0,0 +1,5 @@
<%= todos_calendar_container(:due_today, @calendar.due_today ) %>
<%= todos_calendar_container(:due_this_week, @calendar.due_this_week ) %>
<%= todos_calendar_container(:due_next_week, @calendar.due_next_week ) %>
<%= todos_calendar_container(:due_this_month, @calendar.due_this_month ) %>
<%= todos_calendar_container(:due_after_this_month, @calendar.due_after_this_month) %>

View file

@ -105,7 +105,7 @@
"<%= Preference.human_attribute_name('sms_context') %>" for todos sent in
via email (which could come from an SMS message)</li>
<li>In sendmail/qmail/postfix/whatever, set up an email address
alias to pipe messages to <pre>/usr/bin/bundle exec /PATH/TO/TRACKS/script/rails r -e production 'MessageGateway.receive(STDIN.read)'</pre></li>
alias to pipe messages to <pre>/PATH/TO/TRACKS/bin/rails r -e production 'MessageGateway.receive(STDIN.read)'</pre></li>
<li>Send an email to your newly configured address!</li>
</ul>
<p>You can also use the Rich Todo API to send in tasks like "do laundry @ Home"
@ -116,7 +116,7 @@
You may need to configure your <tt>site.yml</tt> to tell the message gateway to look at the <tt>to:</tt> field or <tt>from:</tt> field to
lookup Tracks' user from the email address in that field. </p>
<p>You can also send all email to a specific Tracks user. Configure mail_dispatch in site.yml to <tt>single_user</tt> and pass the login of the user:
<pre>TRACKS_MAIL_RECEIVER=<%=current_user.login%> usr/bin/bundle exec /PATH/TO/TRACKS/script/rails r -e production 'MessageGateway.receive(STDIN.read)'</pre>
<pre>TRACKS_MAIL_RECEIVER=<%=current_user.login%> /PATH/TO/TRACKS/bin/rails r -e production 'MessageGateway.receive(STDIN.read)'</pre>
</p>
<a name="google_gadget"> </a>

View file

@ -107,7 +107,7 @@
"<%= Preference.human_attribute_name('sms_context') %>" for todos sent in
via email (which could come from an SMS message)</li>
<li>In sendmail/qmail/postfix/whatever, set up an email address
alias to pipe messages to <pre>/usr/bin/bundle exec /PATH/TO/TRACKS/script/rails r -e production 'MessageGateway.receive(STDIN.read)'</pre></li>
alias to pipe messages to <pre>/PATH/TO/TRACKS/bin/rails r -e production 'MessageGateway.receive(STDIN.read)'</pre></li>
<li>Send an email to your newly configured address!</li>
</ul>
<p>You can also use the Rich Todo API to send in tasks like "do laundry @ Home"
@ -118,7 +118,7 @@
You may need to configure your <tt>site.yml</tt> to tell the message gateway to look at the <tt>to:</tt> field or <tt>from:</tt> field to
lookup Tracks' user from the email address in that field. </p>
<p>You can also send all email to a specific Tracks user. Configure mail_dispatch in site.yml to <tt>single_user</tt> and pass the login of the user:
<pre>TRACKS_MAIL_RECEIVER=<%=current_user.login%> usr/bin/bundle exec /PATH/TO/TRACKS/script/rails r -e production 'MessageGateway.receive(STDIN.read)'</pre>
<pre>TRACKS_MAIL_RECEIVER=<%=current_user.login%> /PATH/TO/TRACKS/bin/rails r -e production 'MessageGateway.receive(STDIN.read)'</pre>
</p>
<a name="mailgun"> </a>

View file

@ -109,7 +109,7 @@
verzonden zijn via email (die bijv. komen via een SMS message)</li>
<li>In sendmail/qmail/postfix/whatever, stel een email address
alias in om berichten door te sturen naar
<pre>/usr/bin/bundle exec /PATH/TO/TRACKS/script/rails r -e production 'MessageGateway.receive(STDIN.read)'</pre></li>
<pre>/PATH/TO/TRACKS/bin/rails r -e production 'MessageGateway.receive(STDIN.read)'</pre></li>
<li>Verstuur een email naar het net geconfigureerde e-mail adres!</li>
</ul>
<p>Je kan ook de Rich Todo API gebruiken om acties te maken zoals "do laundry @ Home"
@ -120,7 +120,7 @@
Het kan nodig zijn om jouw <tt>site.yml</tt> te configureren om de message gateway te laten kijken naar het <tt>to:</tt> veld of het <tt>from:</tt> veld om
de Tracks-gebruiker op te zoeken met het emailadres uit dat veld. </p>
<p>Je kan ook alle email naar een specifieke Tracks gebruiker sturen. Stel mail_dispatch in site.yml in op <tt>single_user</tt> en geeft de login van de gebruiker door:
<pre>TRACKS_MAIL_RECEIVER=<%=current_user.login%> usr/bin/bundle exec /PATH/TO/TRACKS/script/rails r -e production 'MessageGateway.receive(STDIN.read)'</pre>
<pre>TRACKS_MAIL_RECEIVER=<%=current_user.login%> /PATH/TO/TRACKS/bin/rails r -e production 'MessageGateway.receive(STDIN.read)'</pre>
</p>
<a name="google_gadget"> </a>

View file

@ -79,6 +79,15 @@ field to <code>ID, created_at, modified_at, completed_at</code> by adding the pa
</code>
</pre>
If you only want to get the active todos, you add the parameter <code>limit_to_active_todos</code> and set it to some value like this:
<pre>
<code>
$ curl -u username:p4ssw0rd -H "Content-Type: text/xml" \
<%= root_url %>todos.xml?limit_to_active_todos=1
</code>
</pre>
<h2>Writing to the API</h2>
<p>The API provides mechanisms for adding, updating and deleting resources using the HTTP methods <code>PUT</code>, <code>POST</code> and <code>DELETE</code> in combination with the content.</p>

View file

@ -31,8 +31,8 @@
<li class="link"><%= (link_to(t('layouts.mobile_navigation.home'), todos_path(:format => 'm'))) -%></li>
<li class="link"><%= (link_to(t('layouts.mobile_navigation.logout'), logout_path(:format => 'm'))) -%></li>
<li class="link"><%= (link_to(t('layouts.mobile_navigation.tickler'), tickler_path(:format => :m))) -%></li>
<li class="link"><%= (link_to(t('layouts.mobile_navigation.calendar'), calendar_path(:format => :m))) -%></li>
<li class="link"><%= (link_to(t('layouts.mobile_navigation.feeds'), feeds_path(:format=>:m))) -%></li>
<li class="link"><%= (link_to(t('layouts.mobile_navigation.full'), todos_path(:format => 'html'))) -%></li>
</ul>
<% end -%>
<%= render :partial => "shared/footer" -%>

View file

@ -30,7 +30,7 @@
<div id="recurring_timespan">
<br/>
<label for="recurring_todo[start_from]"><%= t('todos.recurrence.starts_on') %>:</label><%=
text_field(:recurring_todo, :start_from, "value" => format_date(UserTime.new(current_user).time), "size" => 12, "class" => "Date", "autocomplete" => "off") %><br/>
text_field(:recurring_todo, :start_from, "value" => format_date(Date.current), "size" => 12, "class" => "Date", "autocomplete" => "off") %><br/>
<br/>
<label for="recurring_todo[ends_on]"><%= t('todos.recurrence.ends_on') %>:</label><br/>
<%= radio_button_tag('recurring_todo[ends_on]', 'no_end_date', true)%> <%= t('todos.recurrence.no_end_date') %><br/>

View file

@ -2,7 +2,7 @@
<div class="row-fluid">
<div class="span12">
<p><small>
<%= t('footer.send_feedback', :version => TRACKS_VERSION) %>: <a href="https://www.assembla.com/spaces/tracks-tickets/tickets"><%= t('common.bugs')%></a> |
<%= t('footer.send_feedback', :version => TRACKS_VERSION) %>: <a href="https://github.com/TracksApp/tracks/issues"><%= t('common.bugs')%></a> |
<a href="https://github.com/TracksApp/tracks/wiki"><%= t('common.wiki')%></a> |
<a href="http://groups.google.com/group/TracksApp"><%= t('common.mailing_list')%></a> |
<a href="http://getontracks.org/"><%= t('common.website')%></a> |

View file

@ -1 +1 @@
<div class="footer"><p>Mobile Tracks <%= TRACKS_VERSION %>: <a href="http://groups.google.com/group/TracksApp"><%= t('common.mailing_list')%></a> | <a href="http://getontracks.org/"><%= t('common.website')%></a> | <a href="http://getontracks.org/development/"><%= t('common.contribute')%></a></p></div>
<div class="footer"><p>Tracks <%= TRACKS_VERSION %> Mobile | <%= (link_to(t('layouts.mobile_navigation.full'), todos_path(:format => 'html'))) -%></p></div>

0
app/views/stats/_actions.html.erb Executable file → Normal file
View file

0
app/views/stats/_chart.html.erb Executable file → Normal file
View file

0
app/views/stats/_contexts.html.erb Executable file → Normal file
View file

0
app/views/stats/_projects.html.erb Executable file → Normal file
View file

0
app/views/stats/_tags.html.erb Executable file → Normal file
View file

0
app/views/stats/_totals.html.erb Executable file → Normal file
View file

0
app/views/stats/actions_completion_time_data.html.erb Executable file → Normal file
View file

View file

0
app/views/stats/actions_day_of_week_all_data.html.erb Executable file → Normal file
View file

View file

0
app/views/stats/actions_done_last30days_data.html.erb Executable file → Normal file
View file

0
app/views/stats/actions_running_time_data.html.erb Executable file → Normal file
View file

View file

0
app/views/stats/actions_time_of_day_all_data.html.erb Executable file → Normal file
View file

View file

0
app/views/stats/index.html.erb Executable file → Normal file
View file

0
app/views/stats/pie_chart_data.html.erb Executable file → Normal file
View file

View file

@ -0,0 +1,8 @@
<%=
settings[:show_container] = !collection.empty? || settings[:show_empty_containers]
todos_container(settings) do
todos_container_header(settings) +
todos_container_items(collection, settings)
end
%>

View file

@ -3,7 +3,6 @@
<span class="errors">
<%= get_list_of_error_messages_for(@todo) if @todo %>
</span>
<% this_year = UserTime.new(current_user).date.strftime("%Y").to_i -%>
<h2><label for="todo_description"><%= t('common.description') %></label></h2>
<%= text_field( "todo", "description", "tabindex" => 1, "maxlength" => 100, "size" => 50) %>
<h2><label for="tag_list"><%= t('todos.tags') %></label></h2>
@ -32,7 +31,7 @@ end %>
<%= text_area( "todo", "notes", "cols" => 40, "rows" => 3, "tabindex" => 5) %>
<h2><label for="todo_due"><%= t('todos.due') %></label></h2>
<%= date_select("todo", "due", {:order => [:day, :month, :year],
:start_year => this_year, :include_blank => '--'}, :tabindex => 6) %>
:start_year => Date.current.year, :include_blank => '--'}, :tabindex => 6) %>
<h2><label for="todo_show_from"><%= t('todos.show_from') %></label></h2>
<%= date_select("todo", "show_from", {:order => [:day, :month, :year],
:start_year => this_year, :include_blank => true}, :tabindex => 7) %>
:start_year => Date.current.year, :include_blank => true}, :tabindex => 7) %>

View file

@ -29,7 +29,7 @@ function show_in_tickler_box() {
function regenerate_predecessor_family() {
<%
parents = @predecessors
parents = @predecessors.to_a
until parents.empty?
parent = parents.pop
parents += parent.predecessors -%>

View file

@ -1,13 +0,0 @@
<div id="display_box">
<%= todos_calendar_container(:due_today, @calendar.due_today ) %>
<%= todos_calendar_container(:due_this_week, @calendar.due_this_week ) %>
<%= todos_calendar_container(:due_next_week, @calendar.due_next_week ) %>
<%= todos_calendar_container(:due_this_month, @calendar.due_this_month ) %>
<%= todos_calendar_container(:due_after_this_month, @calendar.due_after_this_month) %>
</div><!-- End of display_box -->
<div class="input_box" id="input_box">
<p><%= link_to('<span class="feed">iCal</span>'.html_safe, {:format => 'ics', :token => current_user.token}, :title => "iCal feed" ) %>
- <%= t('todos.calendar.get_in_ical_format') %></p>
</div>

View file

@ -1,32 +0,0 @@
BEGIN:VCALENDAR
PRODID:-//TRACKS//<%= TRACKS_VERSION %>//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-WR-CALNAME:Tracks
<% for todo in @due_all
due_date = todo.due
overdue_text = ""
if due_date.at_midnight < Time.zone.now.at_midnight
due_date = Time.zone.now
overdue_text = t('todos.overdue') +": "
end
modified = todo.updated_at || todo.created_at
%>BEGIN:VEVENT
DTSTART;VALUE=DATE:<%= due_date.strftime("%Y%m%d") %>
DTEND;VALUE=DATE:<%= (due_date+1.day).strftime("%Y%m%d") %>
DTSTAMP:<%= due_date.strftime("%Y%m%dT%H%M%SZ") %>
UID:<%= todo_url(todo) %>
CLASS:PUBLIC
CATEGORIES:Tracks
CREATED:<%= todo.created_at.strftime("%Y%m%dT%H%M%SZ") %>
DESCRIPTION:<%= format_ical_notes(todo.notes) %>
LAST-MODIFIED:<%= modified.strftime("%Y%m%dT%H%M%SZ") %>
LOCATION:
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:<%= overdue_text + todo.description %>
TRANSP:TRANSPARENT
END:VEVENT
<% end
%>END:VCALENDAR

View file

@ -15,7 +15,7 @@ function replace_updated_predecessor() {
function regenerate_predecessor_family() {
<%
parents = @predecessors
parents = @predecessors.to_a
until parents.empty?
parent = parents.pop
parents += parent.predecessors -%>

View file

@ -159,7 +159,7 @@ function block_predecessors(next_steps) {
function regenerate_predecessor_family(next_steps) {
<%
if @predecessors
parents = @predecessors
parents = @predecessors.to_a
until parents.empty?
parent = parents.pop
parents += parent.predecessors -%>

View file

@ -125,7 +125,7 @@ function update_predecessors(next_steps) {
function regenerate_predecessor_family() {
<%
parents = @todo.predecessors
parents = @todo.predecessors.to_a
until parents.empty?
parent = parents.pop
parents += parent.predecessors

7
bin/cucumber Executable file
View file

@ -0,0 +1,7 @@
#!/usr/bin/env ruby
begin
load File.expand_path("../spring", __FILE__)
rescue LoadError
end
require 'bundler/setup'
load Gem.bin_path('cucumber', 'cucumber')

View file

@ -1,4 +1,8 @@
#!/usr/bin/env ruby
begin
load File.expand_path("../spring", __FILE__)
rescue LoadError
end
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
APP_PATH = File.expand_path('../../config/application', __FILE__)

7
bin/rake Executable file
View file

@ -0,0 +1,7 @@
#!/usr/bin/env ruby
begin
load File.expand_path("../spring", __FILE__)
rescue LoadError
end
require 'bundler/setup'
load Gem.bin_path('rake', 'rake')

18
bin/spring Executable file
View file

@ -0,0 +1,18 @@
#!/usr/bin/env ruby
# This file loads spring without using Bundler, in order to be fast
# It gets overwritten when you run the `spring binstub` command
unless defined?(Spring)
require "rubygems"
require "bundler"
if match = Bundler.default_lockfile.read.match(/^GEM$.*?^ spring \((.*?)\)$.*?^$/m)
ENV["GEM_PATH"] = ([Bundler.bundle_path.to_s] + Gem.path).join(File::PATH_SEPARATOR)
ENV["GEM_HOME"] = ""
Gem.paths = ENV
gem "spring", match[1]
require "spring/binstub"
end
end

View file

@ -4,7 +4,7 @@ require 'rails/all'
# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(:default, Rails.env)
Bundler.require(*Rails.groups)
require 'yaml'
SITE_CONFIG = YAML.load_file(File.join(File.dirname(__FILE__), 'site.yml'))

View file

@ -1,4 +1,4 @@
# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])

View file

@ -1,5 +1,5 @@
# Load the rails application.
# Load the Rails application.
require File.expand_path('../application', __FILE__)
# Initialize the rails application.
Tracksapp::Application.initialize!
# Initialize the Rails application.
Rails.application.initialize!

View file

@ -1,5 +1,5 @@
Tracksapp::Application.configure do
# Settings specified here will take precedence over those in config/application.rb
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# In the development environment your application's code is reloaded on
# every request. This slows down response time but is perfect for development

View file

@ -1,4 +1,4 @@
Tracksapp::Application.configure do
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# Code is not reloaded between requests.

View file

@ -1,4 +1,4 @@
Tracksapp::Application.configure do
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# The test environment is used exclusively to run your application's

View file

@ -1,3 +1,3 @@
# Be sure to restart your server when you modify this file.
Tracksapp::Application.config.session_store :cookie_store, key: '_tracksapp_session'
Rails.application.config.session_store :cookie_store, key: '_tracksapp_session'

View file

@ -1,4 +1,4 @@
Tracksapp::Application.routes.draw do
Rails.application.routes.draw do
mount Tolk::Engine => '/tolk', :as => 'tolk' if Rails.env=='development'
root :to => 'todos#index'

View file

@ -15,7 +15,7 @@ ActiveRecord::Schema.define(version: 20130227205845) do
create_table "contexts", force: true do |t|
t.string "name", null: false
t.integer "position", default: 0
t.integer "position"
t.integer "user_id", default: 1
t.datetime "created_at"
t.datetime "updated_at"
@ -85,11 +85,11 @@ ActiveRecord::Schema.define(version: 20130227205845) do
add_index "preferences", ["user_id"], name: "index_preferences_on_user_id", using: :btree
create_table "projects", force: true do |t|
t.string "name", null: false
t.integer "position", default: 0
t.integer "user_id", default: 1
t.text "description", limit: 16777215
t.string "state", limit: 20, null: false
t.string "name", null: false
t.integer "position"
t.integer "user_id", default: 1
t.text "description"
t.string "state", limit: 20, null: false
t.datetime "created_at"
t.datetime "updated_at"
t.integer "default_context_id"
@ -104,17 +104,17 @@ ActiveRecord::Schema.define(version: 20130227205845) do
add_index "projects", ["user_id"], name: "index_projects_on_user_id", using: :btree
create_table "recurring_todos", force: true do |t|
t.integer "user_id", default: 1
t.integer "context_id", null: false
t.integer "user_id", default: 1
t.integer "context_id", null: false
t.integer "project_id"
t.string "description", null: false
t.text "notes", limit: 16777215
t.string "state", limit: 20, null: false
t.string "description", null: false
t.text "notes"
t.string "state", limit: 20, null: false
t.datetime "start_from"
t.string "ends_on"
t.datetime "end_date"
t.integer "number_of_occurences"
t.integer "occurences_count", default: 0
t.integer "occurences_count", default: 0
t.string "target"
t.integer "show_from_delta"
t.string "recurring_period"
@ -123,7 +123,7 @@ ActiveRecord::Schema.define(version: 20130227205845) do
t.integer "every_other2"
t.integer "every_other3"
t.string "every_day"
t.boolean "only_work_days", default: false
t.boolean "only_work_days", default: false
t.integer "every_count"
t.integer "weekday"
t.datetime "completed_at"
@ -141,7 +141,7 @@ ActiveRecord::Schema.define(version: 20130227205845) do
t.datetime "updated_at"
end
add_index "sessions", ["session_id"], name: "sessions_session_id_index", using: :btree
add_index "sessions", ["session_id"], name: "index_sessions_on_session_id", using: :btree
create_table "taggings", force: true do |t|
t.integer "taggable_id"
@ -162,19 +162,19 @@ ActiveRecord::Schema.define(version: 20130227205845) do
add_index "tags", ["name"], name: "index_tags_on_name", using: :btree
create_table "todos", force: true do |t|
t.integer "context_id", null: false
t.integer "context_id", null: false
t.integer "project_id"
t.string "description", null: false
t.text "notes", limit: 16777215
t.string "description", null: false
t.text "notes"
t.datetime "created_at"
t.datetime "due"
t.datetime "completed_at"
t.integer "user_id", default: 1
t.integer "user_id", default: 1
t.datetime "show_from"
t.string "state", limit: 20, null: false
t.string "state", limit: 20, null: false
t.integer "recurring_todo_id"
t.datetime "updated_at"
t.text "rendered_notes", limit: 16777215
t.text "rendered_notes"
end
add_index "todos", ["context_id"], name: "index_todos_on_context_id", using: :btree
@ -212,7 +212,7 @@ ActiveRecord::Schema.define(version: 20130227205845) do
create_table "users", force: true do |t|
t.string "login", limit: 80, null: false
t.string "crypted_password", limit: 60
t.string "crypted_password", limit: 60, null: false
t.string "token"
t.boolean "is_admin", default: false, null: false
t.string "first_name"

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -3,19 +3,20 @@
* Project homepage: http://getontracks.org/
* Manual: http://getontracks.org/manual/
* Source at GitHub: https://github.com/TracksApp/tracks
* Assembla space (for bug reports and feature requests): https://www.assembla.com/spaces/tracks-tickets/tickets
* Bug reports and feature requests: https://github.com/TracksApp/tracks/issues
* Wiki (community contributed information): https://github.com/TracksApp/tracks/wiki
* Forum (read-only): http://getontracks.org/forums/
* Mailing list: http://groups.google.com/group/TracksApp
* Original developer: bsag (http://www.rousette.org.uk/)
* Contributors: https://github.com/TracksApp/tracks/wiki/Contributors
* Version: 2.3devel
* Copyright: (cc) 2004-2013 rousette.org.uk.
* Copyright: (cc) 2004-2014 rousette.org.uk.
* License: GNU GPL
== Version 2.3devel
New and changed features
* Added new binstubs. The commands `bin/rails` and `bin/rake` take the place of
the old `bundle exec rails` and `bundle exec rake`, respectively.
* You can select to group todos on the home page by context or by
project (using the view menu). This also works for tag page, the project page,
the tickler and the context page

View file

@ -1,12 +1,34 @@
h1. Installing Tracks
The following instructions will guide you through the installation of Tracks from source.
h2. Getting Tracks
This description is intended for people installing Tracks from scratch. If you would like to upgrade an existing installation, please see the "upgrade documentation":upgrading.textile.
Various Tracks users have contributed installation howtos for specific environments. They are "on the wiki":https://github.com/TracksApp/tracks/wiki/Installation-index.
If you are not confident installing Tracks from source using these instructions, there are several alternative options provided by third parties:
* If you'd like to install Tracks on a local machine, try the packaged version offered by "Bitnami":http://bitnami.org/stack/tracks -- it runs on Windows, Mac OS X and Linux.
* If you'd like to run Tracks within a dedicated virtual machine, "JumpBox":http://jumpbox.com/app/tracks provides preconfigured virtual machine images.
* Several providers offer individual Tracks user accounts. A list of these providers can be found "on the wiki":https://github.com/TracksApp/tracks/wiki/Tracks-hosting.
(Please note that these third-party options may use older versions of Tracks.)
h2. Prerequisites
Tracks has a few software requirements that must be satisfied before installation:
# *Ruby*. Tracks requires Ruby 1.9.2 or greater.
# *Bundler*. Tracks requires a recent version of "Bundler":http://bundler.io to handle the installation of dependencies. Bundler is typically installed by running @gem install bundler@.
# *Database*. Tracks is tested on "MySQL":http://www.mysql.com/, but "SQLite":http://www.sqlite.org/ and "PostgreSQL":http://www.postgresql.org/ can also be used. Of the three, SQLite requires the least configuration. Whatever your choice, the appropriate database software must be installed.
h2. Get Tracks
There are two methods of downloading Tracks:
# (Recommended for most people) Download the "zipped package":https://github.com/TracksApp/tracks/archive/v2.2.zip for the latest stable release (2.2) and unzip in your preferred location (e.g. @~/Sites@ for Mac OS X users).
# (Recommended for most people) Download the "zipped package":https://github.com/TracksApp/tracks/archive/v2.2.2.zip for the latest stable release (2.2.2) and unzip in your preferred location (e.g. @~/Sites@ for Mac OS X users).
# If you want to live on the edge, you can get the latest development version from GitHub using git (bear in mind that this may be less stable than the released versions):
bc. cd ~/Sites
@ -14,120 +36,65 @@ git clone https://github.com/TracksApp/tracks.git
cd tracks
h3. Easy installation options
h2. Set up the database
_This section only applies if you will be using Tracks with a MySQL database._
There are a few easy options if you are not confident about installing Tracks from source using these instructions. If you'd like to install Tracks on a local machine, try "BitNami":http://bitnami.org/stack/tracks -- it runs on Windows, Mac OS X and Linux. But they also support preconfigured virtual machines, including Amazon machine images.
Alternatively, you could try "JumpBox":http://jumpbox.com/app/tracks, who provide a JumpBox for Tracks. JumpBoxes are pre-built, pre-configured virtual applications which run in a range of "Virtualization software applications":http://www.jumpbox.com/supported-virtualization-software. You just download the JumpBox (free), then open the file with your Virtualization software. Once the JumpBox has booted, it will give you a URL which you can visit in a browser. The software will then guide you through setting up an account. If you'd like to try out the JumpBox without installing it, you can use the 'Trial This JumpBox' button on the web site, which will let you play around with it to test it out. Furthermore, there is a free public AMI available for Amazon EC2. Just use any EC2 client and search for Tracks. This works in exactly the same way as the downloaded JumpBox you can easily migrate from a downloaded installation to an EC2 instance or back using the backup system of the JumpBox.
Several third parties provide Tracks hosting as a service. A list of these providers can be found "on the wiki":https://github.com/TracksApp/tracks/wiki/Tracks-hosting. Please note that they may run older versions of Tracks.
h3. Requirements
The Tracks interface is accessed through a web browser, so you need to run a webserver to serve the Tracks pages up to you. This isn't as daunting as it sounds, however: Tracks ships with a built-in web server called Mongrel which you can run on your own computer to serve the Tracks application locally. If you want to be able to access Tracks from any computer connected to the Internet, then you need to install Tracks on a publicly accessible server, and you will probably be better off using a more robust web server such as "Apache":http://www.apache.org/ (using "modrails":http://www.modrails.com/) or "Lighttpd":http://www.lighttpd.net/ to serve the pages, particularly if it will be used by many people.
Tracks stores its data in a database, and you can either use SQLite3, MySQL or PostgreSQL. SQLite3 is the best choice for a single user (or a small number of users) on a local installation, while MySQL or PostgreSQL is better for multiple users on a remote installation.
h3. What is included with the Tracks package?
# Tracks itself
# An empty SQLite3 database, set up with the correct database schema
h3. What you need to install
If you don't want to (or can't) use one of the all in one installations, you'll need to install a few things, depending on your platform and your needs.
# *Ruby*. Tracks requires either Ruby 1.8.7 or Ruby 1.9.x. Ruby 1.9.x is the recommended version. Please note that support for ruby 1.8.7 will be dropped after this release!
# *RubyGems*. Tracks was tested on version 1.8.24. You may upgrade using @gem update --system@. The gems needed by Rails to interact with the database have to be compiled on the platform on which they will be run, so we cannot include them with the Tracks package, unlike some other gems. So you will need to "download":http://rubyforge.org/frs/?group_id=126 and install RubyGems (run @ruby setup.rb@ after extracting the package). If you use Linux, rubygems may be available throught your packaging system. Mac OS X users already have RubyGems and the SQLite3 gem already installed on their systems. Once installed you can use RubyGems to install the gems you need for your database. Run @bundle install --without development test@ from the directory you installed Tracks in. This will install all needed gems, including those for MySQL and Sqlite3. If you do not want one of them, you can comment it out in your @Gemfile@ which can be found in the root of the Tracks installation.
# *Database*. The easiest option is to use SQLite3, as the database is included in the package. You may need to install it first for your platform (see "sqlite.org":http://sqlite.org/download.html for downloads and installation instructions). If you want to use MySQL, download and install a package for your platform from "MySQL.com":http://dev.mysql.com/downloads/mysql/5.0.html. The basic steps for Postgresql should be similar to those for MySQL, but they will not be discussed further here.
Various Tracks users have contributed installation howtos for specific setups. They are "on the wiki":https://github.com/TracksApp/tracks/wiki/Installation-index.
h2. Installation
This description is intended for people installing Tracks from scratch. If you would like to upgrade an existing installation, please see the "upgrade documentation":upgrading.textile.
# Unzip tracks and install in a directory
# Decide on a database to use
## SQLite3 - change database.yml to point to SQLite3 database. Make sure you add the complete path to the database. Remove the @mysql2@ gem from the Gemfile
## MySQL - create new MySQL db and grant all privileges
# Install the necessary prerequisites using Bundler
# Configure some variables
# Populate the database with the Tracks schema
# Start the server
# Visit Tracks in a browser
# Customise Tracks
h3. Unzip Tracks and install
Unzip the package and move Tracks into the directory you want to run it from. For example, for Mac OS X users, @~/Sites@ is a good choice.
h3. Decide on a database
Before you go any further, you need to decide which database you will use. See the 'What you need to install' section for details on installing the required components for you choice of database.
# *SQLite3*. All you need to do is make sure that you point Tracks to the included SQLite3 database in @/db@ in the next step, 'Configure variables'.
# *MySQL*. Once you have MySQL installed, you need to create a database and database-user to use with Tracks. For this, you can use MySQL Administrator or go into a terminal and issue the following commands:
You need to create a database and database-user to use with Tracks. For this, you can use MySQL Administrator or go into a terminal and issue the following commands:
bc. mysql -uroot -p
mysql> CREATE DATABASE tracks;
mysql> GRANT ALL PRIVILEGES ON tracks.* TO yourmysqluser@localhost \
IDENTIFIED BY 'password-goes-here' WITH GRANT OPTION;
h3. Install the necessary prerequisites using Bundler
Tracks makes use of several other Ruby libraries (known as 'gems') to provide additional functionality. The Bundler tool makes it easy for the gems that Tracks needs to be installed.
h2. Install dependencies
Tracks is built upon a number of Ruby libraries (known as 'gems'). The Bundler tool makes it easy to install all the gems that Tracks needs, and ensures that they are all the correct versions.
# Make sure you have bundler on your system already. It can be installed by running @gem install bundler@
# Run the command @bundle install --without development test@ in the directory that you unzipped your Tracks download to.
# Wait for Bundler to finish installing the necessary gems that Tracks needs. This can take some time depending on the speed of your internet connection and the speed of the system you're installing Tracks on.
h3. Configure variables
# If you downloaded Tracks via GitHub, you need to duplicate the files @database.yml.tmpl@ and @site.yml.tmpl@ and remove the @*.tmpl@ extension from the duplicates. Once you've made those copies, edit the files as described in steps 2 and 3.
# Open the file @/config/database.yml@ and edit the @production:@ section with the details of your database. If you are using MySQL the @adapter:@ line should read @adapter: mysql2@, @host: localhost@ (in the majority of cases), and your username and password should match those you assigned when you created the database. If you are using SQLite3, you should have only two lines under the production section: @adapter: sqlite3@ and @database: db/tracks-blank.db@.
# Open the file @/config/site.yml@, and read through the settings to make sure that they suit your setup. In most cases, all you need to change are the @salt: "change-me"@ line (change the string "change-me" to some other string of your choice), the administrator email address (@admin_email@), and the time zone setting. For the time zone setting you can use the command @bundle exec rake time:zones:local@ to see all available timezones on your machine
h2. Configure variables
# In the @config@ folder, copy the files @database.yml.tmpl@ and @site.yml.tmpl@ to @database.yml@ and @site.yml@, respectively.
# Open the file @config/database.yml@ and edit the @production:@ section with the details of your database. If you are using MySQL the @adapter:@ line should read @adapter: mysql2@, @host: localhost@ (in the majority of cases), and your username and password should match those you assigned when you created the database. If you are using SQLite3, you should have only two lines under the production section: @adapter: sqlite3@ and @database: db/tracks.db@.
# Open the file @config/site.yml@, and read through the settings to make sure that they suit your setup. In most cases, all you need to change are the @salt: "change-me"@ line (change the string "change-me" to some other string of your choice), the administrator email address (@admin_email@), and the time zone setting. For the time zone setting you can use the command @bin/rake time:zones:local@ to see all available timezones on your machine
# If you are using Windows, you may need to check the 'shebang' lines (@#!/usr/bin/env ruby@) of the @/public/dispatch.*@ files and all the files in the @/script@ directory. They are set to @#!/usr/bin/env ruby@ by default. This should work for all Unix based setups (Linux or Mac OS X), but Windows users will probably have to change it to something like @#c:/ruby/bin/ruby@ to point to the Ruby binary on your system.
# If you intend to deploy Tracks with the built in webserver called WEBrick, you'll need to change @config.serve_static_assets@ to @true@ in @config/environments/production.rb@ in order for the images, stylesheets, and javascript files to be served correctly.
h3. Populate your database with the Tracks schema
h2. Populate your database with the Tracks schema
Open a terminal and change into the root of your Tracks directory. Enter the following command:
bc. bundle exec rake db:migrate RAILS_ENV=production
bc. bin/rake db:migrate RAILS_ENV=production
This will update your database with the required schema for Tracks. If you are using SQLite3, it is not strictly necessary, because the SQLite3 database included with Tracks already has the schema included in it, but it should not do any harm to run the command (nothing will happen if it is up to date).
This will set up your database with the required structure to hold Tracks' data.
h3. Precompile assets
h2. Precompile assets
Static assets (images, stylesheets, and javascript) need to be compiled in order for them to work correctly with the new asset pipeline feature in Rails. Precompiling your assets is as simple as running the following command while inside the Tracks root directory:
bc. bundle exec rake assets:precompile
bc. bin/rake assets:precompile
h3. Start the server
h2. Start the server
While still in the Terminal inside the Tracks root directory, issue the following command:
bc. bundle exec rails server -e production
bc. bin/rails server -e production
If all goes well, you should see some text informing you that the WEBrick server is running: @=> Rails application starting in production on http://0.0.0.0:3000@. If you are already running other services on port 3000, you need to select a different port when running the server, using the @-p@ option. You can stop the server again by the key combination Ctrl-C.
If all goes well, you should see some text informing you that the WEBrick server is running: @=> Rails application starting in production on http://0.0.0.0:3000@. If you are already running other services on port 3000, you need to select a different port when running the server, using the @-p@ option.
h3. Visit Tracks in a browser
h2. Visit Tracks in a browser
Visit @http://0.0.0.0:3000/signup@ in a browser (or whatever URL and port was reported when you started the server in the step above) and chose a user name and password for admin user. Once logged in as admin, you can add other (ordinary level) users. If you need to access Tracks from a mobile/cellular phone browser, visit @http://yourdomain.com/mobile/@. This mobile version is a special, lightweight version of Tracks, designed to use on a mobile browser.
h3. Customise Tracks
h2. Customise Tracks
Once logged in, add some Contexts and Projects, and then go ahead and add your actions. You might also want to visit the Preferences page to edit various settings to your liking. Have fun!

View file

@ -9,9 +9,9 @@ That said. To upgrade:
# Install Tracks 2.3devel in a new directory. Or you can create a separate installation of 2.3 for testing purposes.
# Copy over the configuration from your previous Tracks installation. If using SQLite3, copy the old database into the new Tracks 2.3devel directory.
# Check that you have all dependencies installed: @bundle install --without development test@ Or leave out the @--without development test@ part if you intent to test or develop on this tree.
# Run @bundle exec rake db:migrate RAILS_ENV=production@ to update your old database to the new schema. This is the point of no return. Make sure you have backups!
# Precompile your static assets (css, javascript, etc.) by running @bundle exec rake assets:precompile@.
# Run @bundle exec rails server -e production@ inside your Tracks 2.3devel directory to start up Tracks. Or use @-e development@ if you intent to try your changes and get more log info.
# Run @bin/rake db:migrate RAILS_ENV=production@ to update your old database to the new schema. This is the point of no return. Make sure you have backups!
# Precompile your static assets (css, javascript, etc.) by running @bin/rake assets:precompile@.
# Run @bin/rails server -e production@ inside your Tracks 2.3devel directory to start up Tracks. Or use @-e development@ if you intent to try your changes and get more log info.
Please note that if you intend to use Tracks with the built in webserver called WEBrick for production, you'll need to change @config.serve_static_assets@ to @true@ in @config/environments/production.rb@ in order for the images, stylesheets, and javascript files to be served correctly.

View file

@ -15,7 +15,7 @@ Feature: Add a todo to Tracks on console
And I have a context called "Context A"
And I have a project called "Project A"
@javascript @aruba
@javascript @aruba @wip
Scenario: Create a single todo
Given a console input that looks like
"""
@ -24,7 +24,7 @@ Feature: Add a todo to Tracks on console
When I execute the add-todo script
Then I should have 1 todo in project "Project A"
@javascript @aruba
@javascript @aruba @wip
Scenario: Create multiple todos
Given a console input that looks like
"""

View file

@ -236,6 +236,13 @@ Feature: Edit a next action from every page
When I go to the "project one" project
Then I should see the todo "todo 1"
@javascript
Scenario: I can give a todo without a project a blank project name
Given I have a todo "todo 1" in the context "@pc"
When I go to the home page
And I edit the project of "todo 1" to ""
Then I should see the todo "todo 1"
@javascript
Scenario: I can edit a todo to move it to the tickler
When I go to the home page

View file

@ -1,12 +1,12 @@
When(/^I collapse the context container of "([^"]*)"$/) do |context_name|
toggle = page.find(:xpath, toggle_context_container_xpath(find_context(context_name)))
toggle.should be_visible
expect(toggle).to be_visible
toggle.click
end
When(/^I collapse the project container of "(.*?)"$/) do |project_name|
toggle = page.find(:xpath, toggle_project_container_xpath(find_project(project_name)))
toggle.should be_visible
expect(toggle).to be_visible
toggle.click
end
@ -107,7 +107,7 @@ end
Then /^I should see "([^"]*)" in the due next month container$/ do |todo_description|
within "div#due_after_this_month_container" do
page.should have_css("div#line_todo_#{find_todo(todo_description).id}")
expect(page).to have_css("div#line_todo_#{find_todo(todo_description).id}")
end
end
@ -148,7 +148,7 @@ Then /^I should (see|not see) empty message for (done today|done this week|done
css = "div#deferred_pending_container-empty-d" if state == "deferred todos"
elem = find(css)
elem.should_not be_nil
expect(elem).to_not be_nil
check_elem_visibility(visible, elem)
end

View file

@ -4,10 +4,10 @@ When /^I delete the context "([^\"]*)"$/ do |context_name|
handle_js_confirm do
click_link "delete_context_#{context.id}"
end
get_confirm_text.should == "Are you sure that you want to delete the context '#{context_name}'? Be aware that this will also delete all (repeating) actions in this context!"
expect(get_confirm_text).to eq("Are you sure that you want to delete the context '#{context_name}'? Be aware that this will also delete all (repeating) actions in this context!")
# wait until the context is removed
page.should_not have_css("a#delete_context_#{context.id}")
expect(page).to_not have_css("a#delete_context_#{context.id}")
end
When /^I edit the context to rename it to "([^\"]*)"$/ do |new_name|
@ -61,7 +61,7 @@ When /^I edit the state of context "(.*?)" to closed$/ do |context_name|
end
Then /^context "([^"]*)" should be above context "([^"]*)"$/ do |context_high, context_low|
context_list_find_index(context_high).should < context_list_find_index(context_low)
expect(context_list_find_index(context_high)).to be < context_list_find_index(context_low)
end
Then(/^I should see that a context named "([^"]*)" (is|is not) present$/) do |context_name, present|
@ -87,9 +87,9 @@ Then /^the new context form should (be|not be) visible$/ do |visible|
end
Then /^the context list badge for ([^"]*) contexts should show (\d+)$/ do |state_name, count|
find("span##{state_name}-contexts-count").text.should == count
expect(find("span##{state_name}-contexts-count").text).to eq(count)
end
Then /^I should (see|not see) empty message for (active|hidden|closed) contexts$/ do |visible, state|
check_css_visibility(visible, "div##{state}-contexts-empty-nd")
end
end

View file

@ -5,7 +5,7 @@ end
Given /^there exists (an active|a hidden|a closed) context called "([^"]*)" for user "([^"]*)"$/ do |state, context_name, login|
user = User.where(:login => login).first
user.should_not be_nil
expect(user).to_not be_nil
context_state = {"an active" => "active", "a hidden" => "hidden", "a closed" => "closed"}[state]
@context = user.contexts.where(:name => context_name, :state => context_state).first_or_create
end
@ -63,11 +63,11 @@ end
Then /^he should see that a context named "([^\"]*)" (is|is not) present$/ do |context_name, visible|
context = @current_user.contexts.where(:name => context_name).first
if visible == "is"
context.should_not be_nil
expect(context).to_not be_nil
css = "div#context_#{context.id} div.context_description a"
page.should have_selector(css, :visible => true)
page.find(:css, css).text.should == context_name
expect(page).to have_selector(css, :visible => true)
expect(page.find(:css, css).text).to eq(context_name)
else
page.should_not have_selector("div#context_#{context.id} div.context_description a", :visible => true) if context
expect(page).to_not have_selector("div#context_#{context.id} div.context_description a", :visible => true) if context
end
end
end

View file

@ -18,7 +18,7 @@ end
When /^I expand the dependencies of "([^\"]*)"$/ do |todo_name|
todo = Todo.where(:description=>todo_name).first
todo.should_not be_nil
expect(todo).to_not be_nil
expand_img_locator = "//div[@id='line_todo_#{todo.id}']/div/a[@class='show_successors']/img"
page.find(:xpath, expand_img_locator).click
@ -28,9 +28,9 @@ end
When /^I edit the dependency of "([^"]*)" to add "([^"]*)" as predecessor$/ do |todo_description, predecessor_description|
todo = @current_user.todos.where(:description => todo_description).first
todo.should_not be_nil
expect(todo).to_not be_nil
predecessor = @current_user.todos.where(:description => predecessor_description).first
predecessor.should_not be_nil
expect(predecessor).to_not be_nil
open_edit_form_for(todo)
@ -43,29 +43,29 @@ When /^I edit the dependency of "([^"]*)" to add "([^"]*)" as predecessor$/ do |
page.execute_script %Q{$("#{form_css}").find('input[id$="predecessor_input"]').autocomplete('search')} if Capybara.javascript_driver == :webkit
# wait for auto complete
page.should have_css("a.ui-state-focus")
expect(page).to have_css("a.ui-state-focus")
# click first line
page.find(:css, "ul li a.ui-state-focus").click
# wait for the new dependency to be added to the list
page.should have_css("li#pred_#{predecessor.id}")
expect(page).to have_css("li#pred_#{predecessor.id}")
submit_edit_todo_form(todo)
end
When /^I edit the dependency of "([^"]*)" to remove "([^"]*)" as predecessor$/ do |todo_description, predecessor_description|
todo = @current_user.todos.where(:description => todo_description).first
todo.should_not be_nil
expect(todo).to_not be_nil
predecessor = @current_user.todos.where(:description => predecessor_description).first
predecessor.should_not be_nil
expect(predecessor).to_not be_nil
open_edit_form_for(todo)
delete_dep_button = "//form[@id='form_todo_#{todo.id}']//img[@id='delete_dep_#{predecessor.id}']"
page.find(:xpath, delete_dep_button).click
page.should_not have_xpath(delete_dep_button)
expect(page).to_not have_xpath(delete_dep_button)
submit_edit_todo_form(todo)
wait_for_ajax
@ -74,7 +74,7 @@ end
When /^I edit the dependency of "([^"]*)" to "([^"]*)"$/ do |todo_name, deps|
todo = @dep_todo = @current_user.todos.where(:description => todo_name).first
todo.should_not be_nil
expect(todo).to_not be_nil
open_edit_form_for(todo)
fill_in "predecessor_list_todo_#{todo.id}", :with => deps
@ -83,7 +83,7 @@ end
Then /^the successors of "(.*)" should include "(.*)"$/ do |parent_name, child_name|
parent = @current_user.todos.where(:description => parent_name).first
parent.should_not be_nil
expect(parent).to_not be_nil
# wait until the successor is added. TODO: make this not loop indefinitly
wait_until do
@ -95,7 +95,7 @@ end
Then /^I should see "([^\"]*)" within the dependencies of "([^\"]*)"$/ do |successor_description, todo_description|
todo = @current_user.todos.where(:description => todo_description).first
todo.should_not be_nil
expect(todo).to_not be_nil
# open successors
within "div#line_todo_#{todo.id}" do
@ -109,14 +109,14 @@ end
Then /^I should not see "([^"]*)" within the dependencies of "([^"]*)"$/ do |successor_description, todo_description|
todo = @current_user.todos.where(:description => todo_description).first
todo.should_not be_nil
expect(todo).to_not be_nil
step "I should not see \"#{successor_description}\" within \"div#line_todo_#{todo.id}\""
end
Then /^I should see that "([^"]*)" does not have dependencies$/ do |todo_description|
todo = @current_user.todos.where(:description => todo_description).first
todo.should_not be_nil
expect(todo).to_not be_nil
dependencies_icon = "//div[@id='line_todo_#{todo.id}']/div/a[@class='show_successors']/img"
page.should_not have_xpath(dependencies_icon)
expect(page).to_not have_xpath(dependencies_icon)
end

View file

@ -7,23 +7,23 @@ Then /^I should see a message that you need a project to get feeds for projects$
end
Then /^I should see feeds for projects$/ do
page.should have_css("select#feed-projects option[value='#{@current_user.projects.first.id}']")
expect(page).to have_css("select#feed-projects option[value='#{@current_user.projects.first.id}']")
end
Then /^I should see feeds for contexts$/ do
page.should have_css("select#feed-contexts option[value='#{@current_user.contexts.first.id}']")
expect(page).to have_css("select#feed-contexts option[value='#{@current_user.contexts.first.id}']")
end
Then /^I should see "([^"]*)" as the selected project$/ do |project_name|
page.should have_css 'select#feed-projects option[selected="selected"]'
expect(page).to have_css('select#feed-projects option[selected="selected"]')
end
Then /^I should see "([^"]*)" as the selected context$/ do |context_name|
page.should have_css 'select#feed-contexts option[selected="selected"]'
expect(page).to have_css('select#feed-contexts option[selected="selected"]')
end
Then /^I should see feeds for "([^"]*)" in list of "([^"]*)"$/ do |name, list_type|
wait_for_ajax
xpath= "//div[@id='feeds-for-#{list_type}']//strong"
name.should == find(:xpath, xpath).text
expect(name).to eq(find(:xpath, xpath).text)
end

View file

@ -10,26 +10,21 @@ Given /^I am working on the mobile interface$/ do
@mobile_interface = true
end
Given /^the date is "(.*?)"$/ do |date|
# remember to tag the scenario with @reset_time to reset this travel
Timecop.travel(date)
end
Given(/^I have selected the view for group by (project|context)$/) do |grouping|
@group_view_by = grouping
end
Then /the badge should show (.*)/ do |number|
badge = find("span#badge_count").text.to_i
badge.should == number.to_i
expect(badge).to eq(number.to_i)
end
Then(/^I should see an error flash message saying "([^"]*)"$/) do |message|
xpath = "//div[@id='message_holder']/h4[@id='flash']"
page.should have_xpath(xpath, :visible => true)
expect(page).to have_xpath(xpath, :visible => true)
text = page.find(:xpath, xpath).text
text.should == message
expect(text).to eq(message)
end
Then /^I should see "([^"]*)" $/ do |text|

View file

@ -8,13 +8,13 @@ Then /^I should see scripts$/ do
end
Then /^I should see a script "([^\"]*)" for "([^\"]*)"$/ do |script, context_name|
page.should have_css("##{script}", :visible => true)
expect(page).to have_css("##{script}", :visible => true)
context = Context.where(:name => context_name).first
page.should have_content("#{context.id} (* #{context_name} *)")
expect(page).to have_content("#{context.id} (* #{context_name} *)")
# make sure the text is found within the textarea
script_source = page.find(:xpath, "//textarea[@id='#{script}']").text
script_source.should =~ /#{context.id} \(\* #{context_name} \*\)/
expect(script_source).to match(/#{context.id} \(\* #{context_name} \*\)/)
end

View file

@ -10,9 +10,9 @@ When /^I delete the first note$/ do
handle_js_confirm do
click_link "delete_note_#{id}"
end
get_confirm_text.should == "Are you sure that you want to delete the note '#{id}'?"
expect(get_confirm_text).to eq("Are you sure that you want to delete the note '#{id}'?")
page.should_not have_css("a#delete_note_#{id}")
expect(page).to_not have_css("a#delete_note_#{id}")
end
When /^I click the icon next to the note$/ do
@ -32,7 +32,7 @@ end
When(/^I toggle the note of "([^"]*)"$/) do |todo_description|
todo = @current_user.todos.where(:description => todo_description).first
todo.should_not be_nil
expect(todo).to_not be_nil
xpath = "//div[@id='line_todo_#{todo.id}']/div/a/img"
page.find(:xpath, xpath).click
@ -52,7 +52,7 @@ Then /^(.*) notes should be visible$/ do |number|
# count number of project_notes
count = 0
page.all("div.project_notes").each { |node| count += 1 }
count.should == number.to_i
expect(count).to eq(number.to_i)
end
Then /^I should see note "([^\"]*)" on the "([^\"]*)" project page$/ do |note, project|
@ -71,7 +71,7 @@ Then /^the first note should disappear$/ do
id = title.split(' ').last
note = "div#note_#{id}"
page.should_not have_css(note, :visible=>true)
expect(page).to_not have_css(note, :visible=>true)
end
Then /^I should see the note text$/ do
@ -79,9 +79,9 @@ Then /^I should see the note text$/ do
end
Then /^I should not see the note "([^"]*)"$/ do |note_content|
page.should_not have_selector("div", :text => note_content, :visible => true)
expect(page).to_not have_selector("div", :text => note_content, :visible => true)
end
Then /^I should see the note "([^"]*)"$/ do |note_content|
page.all("div", :text => note_content).first.should be_visible
end
expect(page.all("div", :text => note_content).first).to be_visible
end

View file

@ -1,11 +1,11 @@
When /^I delete project "([^"]*)"$/ do |project_name|
project = @current_user.projects.where(:name => project_name).first
project.should_not be_nil
expect(project).to_not be_nil
handle_js_confirm do
click_link "delete_project_#{project.id}"
end
get_confirm_text.should == "Are you sure that you want to delete the project '#{project_name}'?"
expect(get_confirm_text).to eq("Are you sure that you want to delete the project '#{project_name}'?")
wait_until do
!page.has_css?("a#delete_project_#{project.id}")
@ -40,7 +40,7 @@ When /^I sort the active list alphabetically$/ do
end
wait_for_ajax
end
get_confirm_text.should == "Are you sure that you want to sort these projects alphabetically? This will replace the existing sort order."
expect(get_confirm_text).to eq("Are you sure that you want to sort these projects alphabetically? This will replace the existing sort order.")
end
When /^I sort the active list by number of tasks$/ do
@ -50,7 +50,7 @@ When /^I sort the active list by number of tasks$/ do
end
wait_for_ajax
end
get_confirm_text.should == "Are you sure that you want to sort these projects by the number of tasks? This will replace the existing sort order."
expect(get_confirm_text).to eq("Are you sure that you want to sort these projects by the number of tasks? This will replace the existing sort order.")
end
Then /^I should see that a project named "([^"]*)" is not present$/ do |project_name|
@ -75,34 +75,34 @@ end
Then(/^I should not see the project "(.*?)"$/) do |project_name|
project = @current_user.projects.where(:name => project_name).first
project.should_not be_nil
expect(project).to_not be_nil
project_xpath = "//div[@id='project_#{project.id}']"
page.should_not have_xpath(project_xpath)
expect(page).to_not have_xpath(project_xpath)
end
Then /^the project "([^"]*)" should be above the project "([^"]*)"$/ do |project_high, project_low|
project_list_find_index(project_high).should < project_list_find_index(project_low)
expect(project_list_find_index(project_high)).to be < project_list_find_index(project_low)
end
Then /^the project "([^"]*)" should not be in state list "([^"]*)"$/ do |project_name, state_name|
project = @current_user.projects.where(:name => project_name).first
project.should_not be_nil
expect(project).to_not be_nil
list_id = @source_view=="review" ? "list-#{state}-projects" : "list-#{state_name}-projects-container"
xpath = "//div[@id='#{list_id}']//div[@id='project_#{project.id}']"
page.should_not have_xpath(xpath)
expect(page).to_not have_xpath(xpath)
end
Then /^the project "([^"]*)" should be in state list "([^"]*)"$/ do |project_name, state_name|
project = @current_user.projects.where(:name => project_name).first
project.should_not be_nil
expect(project).to_not be_nil
list_id = @source_view=="review" ? "list-#{state_name}-projects" : "list-#{state_name}-projects-container"
xpath = "//div[@id='#{list_id}']//div[@id='project_#{project.id}']"
page.should have_xpath(xpath)
expect(page).to have_xpath(xpath)
end
Then /^I see the project "([^"]*)" in the "([^"]*)" list$/ do |project_name, state_name|
@ -110,27 +110,27 @@ Then /^I see the project "([^"]*)" in the "([^"]*)" list$/ do |project_name, sta
end
Then /^the project list badge for "([^"]*)" projects should show (\d+)$/ do |state_name, count|
page.find(:xpath, "//span[@id='#{state_name}-projects-count']").text.should == count
expect(page.find(:xpath, "//span[@id='#{state_name}-projects-count']").text).to eq(count)
end
Then /^the new project form should be visible$/ do
page.should have_css("div#project_new", :visible => true)
expect(page).to have_css("div#project_new", :visible => true)
end
Then /^the new project form should not be visible$/ do
page.should_not have_css("div#project_new", :visible => true)
expect(page).to_not have_css("div#project_new", :visible => true)
end
Then /^the project "([^"]*)" should have (\d+) actions listed$/ do |project_name, count|
project = @current_user.projects.where(:name => project_name).first
project.should_not be_nil
expect(project).to_not be_nil
xpath = "//div[@id='list-active-projects-container']//div[@id='project_#{project.id}']//span[@class='needsreview']"
page.find(:xpath, xpath).text.should == "#{project.name} (#{count} actions)"
expect(page.find(:xpath, xpath).text).to eq("#{project.name} (#{count} actions)")
end
Then /^the project "([^"]*)" should have (\d+) deferred actions listed$/ do |project_name, deferred|
project = @current_user.projects.where(:name => project_name).first
project.should_not be_nil
expect(project).to_not be_nil
xpath = "//div[@id='list-active-projects-container']//div[@id='project_#{project.id}']//span[@class='needsreview']"
page.find(:xpath, xpath).text.should == "#{project.name} (#{deferred} deferred actions)"
end
expect(page.find(:xpath, xpath).text).to eq("#{project.name} (#{deferred} deferred actions)")
end

View file

@ -42,7 +42,7 @@ end
Given /^there exists a project (?:|called )"([^"]*)" for user "([^"]*)"$/ do |project_name, user_name|
user = User.where(:login => user_name).first
user.should_not be_nil
expect(user).to_not be_nil
@project = user.projects.create!(:name => project_name)
# acts_as_list adds at top by default, but that is counter-intuitive when reading scenario's, so reverse this
@project.move_to_bottom
@ -73,7 +73,7 @@ Given /^I have a (completed|hidden) project called "([^"]*)"$/ do |state, projec
step "I have a project called \"#{project_name}\""
@project.send(state=="completed" ? "complete!" : "hide!")
@project.reload
assert @project.send(state=="completed" ? "completed?" : "hidden?")
expect(@project.send(state=="completed" ? "completed?" : "hidden?")).to be true
end
Given /^I have (\d+) completed projects$/ do |number_of_projects|
@ -102,7 +102,7 @@ end
Given /^the default tags for "(.*?)" are "(.*?)"$/ do |project_name, default_tags|
project = @current_user.projects.where(:name => project_name).first
project.should_not be_nil
expect(project).to_not be_nil
project.default_tags = default_tags
project.save!
@ -110,12 +110,12 @@ end
When /^I open the project edit form$/ do
click_link "link_edit_project_#{@project.id}"
page.should have_css("button#submit_project_#{@project.id}", :visible => true)
expect(page).to have_css("button#submit_project_#{@project.id}", :visible => true)
end
When /^I cancel the project edit form$/ do
click_link "cancel_project_#{@project.id}"
page.should_not have_css("submit_project_#{@project.id}")
expect(page).to_not have_css("submit_project_#{@project.id}")
wait_for_animations_to_end
end
@ -147,13 +147,13 @@ end
When /^I edit the project name of "([^"]*)" to "([^"]*)"$/ do |project_current_name, project_new_name|
@project = @current_user.projects.where(:name => project_current_name).first
@project.should_not be_nil
expect(@project).to_not be_nil
step "I edit the project name to \"#{project_new_name}\""
end
When /^I try to edit the project name of "([^"]*)" to "([^"]*)"$/ do |project_current_name, project_new_name|
@project = @current_user.projects.where(:name => project_current_name).first
@project.should_not be_nil
expect(@project).to_not be_nil
step "I try to edit the project name to \"#{project_new_name}\""
end
@ -168,14 +168,14 @@ When /^I click to edit the project name in place$/ do
end
When /^I edit the project settings$/ do
@project.should_not be_nil
expect(@project).to_not be_nil
click_link "link_edit_project_#{@project.id}"
page.should have_xpath("//div[@id='edit_project_#{@project.id}']/form//button[@id='submit_project_#{@project.id}']")
expect(page).to have_xpath("//div[@id='edit_project_#{@project.id}']/form//button[@id='submit_project_#{@project.id}']")
end
When /^I close the project settings$/ do
@project.should_not be_nil
expect(@project).to_not be_nil
click_link "Cancel"
wait_for_ajax
wait_for_animations_to_end
@ -183,7 +183,7 @@ end
When /^I edit the project state of "([^"]*)" to "([^"]*)"$/ do |project_name, state_name|
project = @current_user.projects.where(:name => project_name).first
project.should_not be_nil
expect(project).to_not be_nil
edit_project_settings(project) do
choose "project_state_#{state_name}"
@ -192,7 +192,7 @@ end
When /^I edit project "([^"]*)" and mark the project as reviewed$/ do |project_name|
project = @current_user.projects.where(:name => project_name).first
project.should_not be_nil
expect(project).to_not be_nil
open_project_edit_form(project)
click_link "reviewed_project_#{project.id}"
@ -207,11 +207,11 @@ When /^I add a note "([^"]*)" to the project$/ do |note_body|
submit_button = "div.widgets button#submit_note"
click_link "Add a note"
page.should have_css submit_button
expect(page).to have_css submit_button
fill_in "note[body]", :with => note_body
elem = find(submit_button)
elem.should_not be_nil
expect(elem).to_not be_nil
elem.click
wait_until do
@ -221,9 +221,9 @@ When /^I add a note "([^"]*)" to the project$/ do |note_body|
end
When /^I click on the first note icon$/ do
@project.should_not be_nil
expect(@project).to_not be_nil
@note = @project.notes.first # assume first note is also first on screen
@note.should_not be_nil
expect(@note).to_not be_nil
click_link "link_note_#{@note.id}"
end
@ -242,44 +242,44 @@ end
Then /^I should be able to change the project name in place$/ do
# Note that this is not changing the project name
page.should have_css("span#project_name>form>input")
expect(page).to have_css("span#project_name>form>input")
page.find("span#project_name > form > button[type=cancel]").click
page.should_not have_css("span#project_name>form>input")
expect(page).to_not have_css("span#project_name>form>input")
end
Then /^I should not be able to change the project name in place$/ do
step "I click to edit the project name in place"
page.should_not have_xpath("//span[@id='project_name']/form/input")
expect(page).to_not have_xpath("//span[@id='project_name']/form/input")
end
Then /^the form for adding a note should not be visible$/ do
page.should_not have_css("edit_form_note")
expect(page).to_not have_css("edit_form_note")
end
Then /^I should go to that note page$/ do
current_path = URI.parse(current_url).path
note_path = note_path(@note)
current_path.should == note_path
expect(current_path).to eq(note_path)
end
Then /^I should see one note in the project$/ do
page.should have_xpath("//div[@class='note_wrapper']")
expect(page).to have_xpath("//div[@class='note_wrapper']")
end
Then /^I should see the bold text "([^\"]*)" in the project description$/ do |text_in_bold|
xpath="//div[@class='project_description']/p/strong"
page.should have_xpath(xpath)
expect(page).to have_xpath(xpath)
bold_text = page.find(:xpath, xpath).text
bold_text.should =~ /#{text_in_bold}/
expect(bold_text).to match(/#{text_in_bold}/)
end
Then /^I should see the italic text "([^\"]*)" in the project description$/ do |text_in_italic|
xpath="//div[@class='project_description']/p/em"
page.should have_xpath(xpath)
expect(page).to have_xpath(xpath)
italic_text = page.find(:xpath, xpath).text
italic_text.should =~ /#{text_in_italic}/
expect(italic_text).to match(/#{text_in_italic}/)
end
Then /^the project title should be "(.*)"$/ do |title|
@ -295,24 +295,24 @@ end
Then /^I should (see|not see) the default project settings$/ do |visible|
default_settings = "This project is active with no default context and with no default tags"
page.should have_css("div.project_settings")
expect(page).to have_css("div.project_settings")
elem = page.find("div.project_settings")
if visible == "see"
elem.should be_visible
elem.text.should =~ /#{default_settings}/
expect(elem).to be_visible
expect(elem.text).to match(/#{default_settings}/)
else
elem.should_not be_visible
expect(elem).to_not be_visible
end
end
Then /^I should have a project called "([^"]*)"$/ do |project_name|
project = @current_user.projects.where(:name => project_name).first
project.should_not be_nil
expect(project).to_not be_nil
end
Then /^I should have (\d+) todo in project "([^"]*)"$/ do |todo_count, project_name|
project = @current_user.projects.where(:name => project_name).first
project.should_not be_nil
project.todos.count.should == todo_count.to_i
expect(project).to_not be_nil
expect(project.todos.count).to eq(todo_count.to_i)
end

View file

@ -14,7 +14,7 @@ Given /^I have a repeat pattern called "([^"]*)"$/ do |pattern_name|
:created_at => Time.now - 1.day,
:completed_at => nil
)
@recurring_todo.completed?.should be_false
expect(@recurring_todo.completed?).to be false
@todo = @current_user.todos.create!(
:description => pattern_name,
:context_id => context.id,
@ -24,7 +24,7 @@ end
Given /^I have a completed repeat pattern "([^"]*)"$/ do |pattern_name|
step "I have a repeat pattern called \"#{pattern_name}\""
@recurring_todo.toggle_completion!
@recurring_todo.completed?.should be_true
expect(@recurring_todo.completed?).to be true
end
Given /^I have (\d+) completed repeat patterns$/ do |number_of_patterns|
@ -39,39 +39,39 @@ end
When /^I edit the name of the pattern "([^\"]*)" to "([^\"]*)"$/ do |pattern_name, new_name|
pattern = @current_user.recurring_todos.where(:description => pattern_name).first
pattern.should_not be_nil
expect(pattern).to_not be_nil
click_link "link_edit_recurring_todo_#{pattern.id}"
page.should have_css("input#edit_recurring_todo_description")
expect(page).to have_css("input#edit_recurring_todo_description")
fill_in "edit_recurring_todo_description", :with => new_name
page.find("button#recurring_todo_edit_update_button").click
page.should_not have_css("div#edit-recurring-todo", :visible => true)
expect(page).to_not have_css("div#edit-recurring-todo", :visible => true)
end
When /^I star the pattern "([^\"]*)"$/ do |pattern_name|
pattern = @current_user.recurring_todos.where(:description => pattern_name).first
pattern.should_not be_nil
expect(pattern).to_not be_nil
click_link "star_icon_#{pattern.id}"
end
When /^I delete the pattern "([^"]*)"$/ do |pattern_name|
pattern = @current_user.recurring_todos.where(:description => pattern_name).first
pattern.should_not be_nil
expect(pattern).to_not be_nil
handle_js_confirm do
click_link "delete_icon_#{pattern.id}"
end
get_confirm_text.should == "Are you sure that you want to delete the recurring action '#{pattern_name}'?"
expect(get_confirm_text).to eq("Are you sure that you want to delete the recurring action '#{pattern_name}'?")
page.should_not have_css("#delete_icon_#{pattern.id}")
expect(page).to_not have_css("#delete_icon_#{pattern.id}")
end
When /^I mark the pattern "([^"]*)" as (complete|active)$/ do |pattern_name, state|
pattern = @current_user.recurring_todos.where(:description => pattern_name).first
pattern.should_not be_nil
pattern.completed?.should(state=="complete" ? be_false : be_true)
expect(pattern).to_not be_nil
expect(pattern.completed?).to be (state != "complete")
page.find("#check_#{pattern.id}").click
wait_for_ajax
wait_for_animations_to_end
@ -79,7 +79,7 @@ end
When /^I follow the recurring todo link of "([^"]*)"$/ do |action_description|
todo = @current_user.todos.where(:description => action_description).first
todo.should_not be_nil
expect(todo).to_not be_nil
page.find(:xpath, "//div[@id='todo_#{todo.id}']//a[@class='recurring_icon']/img").click
sleep 1 # wait for page to load
@ -89,21 +89,21 @@ Then /^the state list "([^"]*)" should be empty$/ do |state|
empty_id = "recurring-todos-empty-nd" if state.downcase == "active"
empty_id = "completed-empty-nd" if state.downcase == "completed"
empty_msg = page.find("div##{empty_id}")
empty_msg.visible?.should be_true
expect(empty_msg.visible?).to be true
end
Then /^the pattern "([^\"]*)" should be starred$/ do |pattern_name|
pattern = @current_user.recurring_todos.where(:description => pattern_name).first
pattern.should_not be_nil
page.should have_xpath("//div[@id='recurring_todo_#{pattern.id}']//img[@class='todo_star starred']")
expect(pattern).to_not be_nil
expect(page).to have_xpath("//div[@id='recurring_todo_#{pattern.id}']//img[@class='todo_star starred']")
end
Then /^I should see the form for "([^\"]*)" recurrence pattern$/ do |recurrence_period|
page.should have_css("#recurring_#{recurrence_period.downcase}", :visible => true)
expect(page).to have_css("#recurring_#{recurrence_period.downcase}", :visible => true)
end
Then /^the pattern "([^"]*)" should be in the state list "([^"]*)"$/ do |pattern_name, state_name|
pattern = @current_user.recurring_todos.where(:description => pattern_name).first
pattern.should_not be_nil
page.should have_xpath("//div[@id='#{state_name}_recurring_todos_container']//div[@id='recurring_todo_#{pattern.id}']")
expect(pattern).to_not be_nil
expect(page).to have_xpath("//div[@id='#{state_name}_recurring_todos_container']//div[@id='recurring_todo_#{pattern.id}']")
end

View file

@ -1,15 +1,15 @@
Then /^the single action form should be visible$/ do
page.should have_css("#todo_new_action", :visible => true)
expect(page).to have_css("#todo_new_action", :visible => true)
end
Then /^the single action form should not be visible$/ do
page.should_not have_css("#todo_new_action", :visible=>true)
expect(page).to_not have_css("#todo_new_action", :visible=>true)
end
Then /^the multiple action form should be visible$/ do
page.should have_css("#todo_multi_add", :visible => true)
expect(page).to have_css("#todo_multi_add", :visible => true)
end
Then /^the multiple action form should not be visible$/ do
page.should_not have_css("#todo_multi_add", :visible=>true)
expect(page).to_not have_css("#todo_multi_add", :visible=>true)
end

View file

@ -4,7 +4,7 @@ When /^I click on the chart for actions done in the last 12 months$/ do
end
Then /^I should see a chart$/ do
page.should have_css("div.open-flash-chart")
expect(page).to have_css("div.open-flash-chart")
end
When /^I click on the chart for running time of all incomplete actions$/ do

View file

@ -17,7 +17,7 @@ Given(/^I have a todo "([^"]*)" in the context "([^"]*)" in the project "([^"]*)
step "I have a todo \"#{description}\" in the context \"#{context_name}\""
@project = @current_user.projects.where(:name => project_name).first_or_create
@project.should_not be_nil
expect(@project).to_not be_nil
@todo.project = @project
@todo.save!
@ -189,7 +189,7 @@ end
Given /^I have a project "([^"]*)" that has the following (todos|deferred todos)$/ do |project_name, kind_of_todo, todos|
step "I have a project called \"#{project_name}\""
@project.should_not be_nil
expect(@project).to_not be_nil
todos.hashes.each do |todo|
new_todo = @current_user.todos.create!(
@ -242,7 +242,7 @@ When /^I submit a new action with description "([^"]*)" with a dependency on "([
click_first_line_of_auto_complete
new_dependency_line = "//li[@id='pred_#{predecessor.id}']"
page.should have_xpath(new_dependency_line, :visible => true)
expect(page).to have_xpath(new_dependency_line, :visible => true)
submit_next_action_form
end

View file

@ -2,7 +2,7 @@
When /^I mark "([^"]*)" as complete$/ do |action_description|
todo = @current_user.todos.where(:description => action_description).first
todo.should_not be_nil
expect(todo).to_not be_nil
check "mark_complete_#{todo.id}"
@ -12,7 +12,7 @@ end
When /^I mark "([^"]*)" as uncompleted$/ do |action_description|
todo = @current_user.todos.where(:description => action_description).first
todo.should_not be_nil
expect(todo).to_not be_nil
uncheck "mark_complete_#{todo.id}"
@ -30,12 +30,12 @@ end
When /^I star the action "([^"]*)"$/ do |action_description|
todo = @current_user.todos.where(:description => action_description).first
todo.should_not be_nil
expect(todo).to_not be_nil
xpath_unstarred = "//div[@id='line_todo_#{todo.id}']//img[@class='todo_star']"
xpath_starred = "//div[@id='line_todo_#{todo.id}']//img[@class='todo_star starred']"
page.should have_xpath(xpath_unstarred)
expect(page).to have_xpath(xpath_unstarred)
star_img = "//img[@id='star_img_#{todo.id}']"
page.find(:xpath, star_img).click
@ -43,22 +43,22 @@ When /^I star the action "([^"]*)"$/ do |action_description|
wait_for_ajax
wait_for_animations_to_end
page.should have_xpath(xpath_starred)
expect(page).to have_xpath(xpath_starred)
end
When /^I unstar the action "([^"]*)"$/ do |action_description|
todo = @current_user.todos.where(:description => action_description).first
todo.should_not be_nil
expect(todo).to_not be_nil
xpath_unstarred = "//div[@id='line_todo_#{todo.id}']//img[@class='todo_star']"
xpath_starred = "//div[@id='line_todo_#{todo.id}']//img[@class='todo_star starred']"
page.should have_xpath(xpath_starred)
expect(page).to have_xpath(xpath_starred)
star_img = "//img[@id='star_img_#{todo.id}']"
page.find(:xpath, star_img).click
page.should have_xpath(xpath_unstarred)
expect(page).to have_xpath(xpath_unstarred)
end
####### Editing a todo using Edit Form #######
@ -87,7 +87,7 @@ end
When /^I edit the description of "([^"]*)" to "([^"]*)"$/ do |action_description, new_description|
todo = @current_user.todos.where(:description => action_description).first
todo.should_not be_nil
expect(todo).to_not be_nil
open_edit_form_for(todo)
within "form.edit_todo_form" do
@ -98,7 +98,7 @@ end
When /^I try to edit the description of "([^"]*)" to "([^"]*)"$/ do |action_description, new_description|
todo = @current_user.todos.where(:description => action_description).first
todo.should_not be_nil
expect(todo).to_not be_nil
open_edit_form_for(todo)
within "form.edit_todo_form" do
@ -112,7 +112,7 @@ end
When /^I edit the due date of "([^"]*)" to "([^"]*)"$/ do |action_description, date|
todo = @current_user.todos.where(:description => action_description).first
todo.should_not be_nil
expect(todo).to_not be_nil
open_edit_form_for(todo)
fill_in "due_todo_#{todo.id}", :with => date
@ -131,7 +131,7 @@ end
When /^I clear the due date of "([^"]*)"$/ do |action_description|
todo = @current_user.todos.where(:description => action_description).first
todo.should_not be_nil
expect(todo).to_not be_nil
open_edit_form_for(todo)
# use all()[0] to get the first todo. This is for calendar page where you can have
@ -147,7 +147,7 @@ end
When /^I edit the show from date of "([^"]*)" to next month$/ do |action_description|
todo = @current_user.todos.where(:description => action_description).first
todo.should_not be_nil
expect(todo).to_not be_nil
open_edit_form_for(todo)
fill_in "show_from_todo_#{todo.id}", :with => format_date(todo.created_at + 1.month)
@ -156,7 +156,7 @@ end
When /^I remove the show from date from "([^"]*)"$/ do |action_description|
todo = @current_user.todos.where(:description => action_description).first
todo.should_not be_nil
expect(todo).to_not be_nil
open_edit_form_for(todo)
page.find(:xpath, "//div[@id='edit_todo_#{todo.id}']//a[@id='show_from_x_todo_#{todo.id}']/img").click
@ -169,7 +169,7 @@ end
When /^I defer "([^"]*)" for 1 day$/ do |action_description|
todo = @current_user.todos.where(:description => action_description).first
todo.should_not be_nil
expect(todo).to_not be_nil
open_submenu_for(todo) do
click_link "defer_1_todo_#{todo.id}"
@ -181,7 +181,7 @@ end
When /^I edit the tags of "([^"]*)" to "([^"]*)"$/ do |action_description, tags|
todo = @current_user.todos.where(:description => action_description).first
todo.should_not be_nil
expect(todo).to_not be_nil
open_edit_form_for(todo)
within "form#form_todo_#{todo.id}" do
@ -192,13 +192,13 @@ end
When /^I make a project of "([^"]*)"$/ do |action_description|
todo = @current_user.todos.where(:description => action_description).first
todo.should_not be_nil
expect(todo).to_not be_nil
open_submenu_for(todo) do
click_link "to_project_todo_#{todo.id}"
end
page.should have_no_css("div#line_todo_#{todo.id}")
expect(page).to have_no_css("div#line_todo_#{todo.id}")
wait_for_ajax
wait_for_animations_to_end
end
@ -207,5 +207,5 @@ end
Then /^I should see an error message$/ do
error_block = "//form/div[@id='edit_error_status']"
page.should have_xpath(error_block)
expect(page).to have_xpath(error_block)
end

View file

@ -12,7 +12,7 @@ When /^I delete the action "([^"]*)"$/ do |action_description|
click_link "delete_todo_#{todo.id}"
end
end
get_confirm_text.should == "Are you sure that you want to delete the action '#{todo.description}'?"
expect(get_confirm_text).to eq("Are you sure that you want to delete the action '#{todo.description}'?")
wait_for_ajax
end
@ -25,135 +25,135 @@ end
When /^I open the notes of "([^"]*)"$/ do |action_description|
todo = @current_user.todos.where(:description => action_description).first
todo.should_not be_nil
expect(todo).to_not be_nil
page.find(:xpath, "//div[@id='line_todo_#{todo.id}']/div/a/img").click
page.should have_xpath("//div[@id='notes_todo_#{todo.id}']", :visible=>true)
expect(page).to have_xpath("//div[@id='notes_todo_#{todo.id}']", :visible=>true)
end
####### THEN #######
Then /^I should see a starred "([^"]*)"$/ do |action_description|
todo = @current_user.todos.where(:description => action_description).first
todo.should_not be_nil
expect(todo).to_not be_nil
xpath_starred = "//div[@id='line_todo_#{todo.id}']//img[@class='todo_star starred']"
page.should have_xpath(xpath_starred)
expect(page).to have_xpath(xpath_starred)
end
Then /^I should see an unstarred "([^"]*)"$/ do |action_description|
todo = @current_user.todos.where(:description => action_description).first
todo.should_not be_nil
expect(todo).to_not be_nil
xpath_starred = "//div[@id='line_todo_#{todo.id}']//img[@class='todo_star']"
page.should have_xpath(xpath_starred)
expect(page).to have_xpath(xpath_starred)
end
Then /^I should see ([0-9]+) todos$/ do |count|
total = page.all("div.item-container").inject(0) { |s, e| s+=1 }
total.should == count.to_i
expect(total).to eq(count.to_i)
end
Then /^I should see the todo "([^\"]*)"$/ do |todo_description|
page.should have_xpath("//span[.=\"#{todo_description}\"]", :visible => true)
expect(page).to have_xpath("//span[.=\"#{todo_description}\"]", :visible => true)
end
Then /^I should not see the todo "([^\"]*)"$/ do |todo_description|
page.should_not have_xpath("//span[.=\"#{todo_description}\"]", :visible => true)
expect(page).to_not have_xpath("//span[.=\"#{todo_description}\"]", :visible => true)
end
Then /^I should see a completed todo "([^"]*)"$/ do |todo_description|
todo = @current_user.todos.where(:description => todo_description).first
todo.should_not be_nil
expect(todo).to_not be_nil
# only completed todos have a grey span with the completed_at date
xpath = "//div[@id='line_todo_#{todo.id}']/div/span[@class='grey']"
page.should have_xpath(xpath, :visible=>true)
expect(page).to have_xpath(xpath, :visible=>true)
end
Then /^I should see an active todo "([^"]*)"$/ do |todo_description|
todo = @current_user.todos.where(:description => todo_description).first
todo.should_not be_nil
expect(todo).to_not be_nil
xpath = "//div[@id='line_todo_#{todo.id}']/img[@class='grip']"
page.should have_xpath(xpath, :visible=>true)
expect(page).to have_xpath(xpath, :visible=>true)
end
Then /^the number of actions should be (\d+)$/ do |count|
@current_user.todos.count.should == count.to_i
expect(@current_user.todos.count).to eq(count.to_i)
end
Then /^a confirmation for adding a new context "([^"]*)" should be asked$/ do |context_name|
get_confirm_text.should == "New context '#{context_name}' will be also created. Are you sure?"
expect(get_confirm_text).to eq("New context '#{context_name}' will be also created. Are you sure?")
end
Then /^the selected project should be "([^"]*)"$/ do |content|
# Works for mobile. TODO: make it work for both mobile and non-mobile
if content.blank?
page.has_css?("select#todo_project_id option[selected='selected']").should be_false
expect(page.has_css?("select#todo_project_id option[selected='selected']")).to be false
else
page.find("select#todo_project_id option[selected='selected']").text.should =~ /#{content}/
expect(page.find("select#todo_project_id option[selected='selected']").text).to match(/#{content}/)
end
end
Then /^the selected context should be "([^"]*)"$/ do |content|
# Works for mobile. TODO: make it work for both mobile and non-mobile
if content.blank?
page.has_css?("select#todo_context_id option[selected='selected']").should be_false
expect(page.has_css?("select#todo_context_id option[selected='selected']")).to be false
else
page.find("select#todo_context_id option[selected='selected']").text.should =~ /#{content}/
expect(page.find("select#todo_context_id option[selected='selected']").text).to match(/#{content}/)
end
end
Then /^I should see the page selector$/ do
page.should have_xpath(".//a[@class='next_page']")
expect(page).to have_xpath(".//a[@class='next_page']")
end
Then /^the page should be "([^"]*)"$/ do |page_number|
page.find(:xpath, ".//div[@class='paginate_header']//em[@class='current']").text.should == page_number
expect(page.find(:xpath, ".//div[@class='paginate_header']//em[@class='current']").text).to eq(page_number)
end
Then /^the project field of the new todo form should contain "([^"]*)"$/ do |project_name|
xpath= "//form[@id='todo-form-new-action']/input[@id='todo_project_name']"
project_name.should == page.find(:xpath, xpath).value
expect(project_name).to eq(page.find(:xpath, xpath).value)
end
Then /^the default context of the new todo form should be "([^"]*)"$/ do |context_name|
xpath= "//form[@id='todo-form-new-action']/input[@id='todo_context_name']"
context_name.should == page.find(:xpath, xpath).value
expect(context_name).to eq(page.find(:xpath, xpath).value)
end
Then /^the tag field in the new todo form should be empty$/ do
xpath= "//form[@id='todo-form-new-action']/input[@id='tag_list']"
page.find(:xpath, xpath).value.blank?.should be_true
expect(page.find(:xpath, xpath).value).to be_blank
end
Then /^the tag field in the new todo form should be "([^"]*)"$/ do |tag_list|
xpath= "//form[@id='todo-form-new-action']/input[@id='tag_list']"
tag_list.should == page.find(:xpath, xpath).value
expect(tag_list).to eq(page.find(:xpath, xpath).value)
end
Then /^the tags of "([^"]*)" should be "([^"]*)"$/ do |todo_description, tag_list|
find_todo(todo_description).tag_list.should == tag_list
expect(find_todo(todo_description).tag_list).to eq(tag_list)
end
Then /^I should see "([^"]*)" in the completed section of the mobile site$/ do |desc|
todo = @current_user.todos.where(:description => desc).first
todo.should_not be_nil
expect(todo).to_not be_nil
xpath = "//div[@id='completed_container']//a[@href='/todos/#{todo.id}.m']"
page.should have_xpath(xpath)
expect(page).to have_xpath(xpath)
end
Then /^I should (see|not see) the notes of "([^"]*)"$/ do |visible, todo_description|
todo = @current_user.todos.where(:description => todo_description).first
todo.should_not be_nil
expect(todo).to_not be_nil
page.find("div#notes_todo_#{todo.id}").send(visible=="see" ? "should" : "should_not", be_visible)
expect(page.find("div#notes_todo_#{todo.id}")).send(visible=="see" ? :to : :to_not, be_visible)
end
Then /^I should (see|not see) the empty tickler message$/ do |see|
elem = find("div#no_todos_in_view")
elem.send(see=="see" ? "should" : "should_not", be_visible)
expect(elem).send(see=="see" ? :to : :to_not, be_visible)
end

View file

@ -19,13 +19,13 @@ Given /^the following user records with hash algorithm$/ do |table|
when 'bcrypt'
user.change_password( password, password )
user.reload
BCrypt::Password.new(user.crypted_password).should == password
expect(BCrypt::Password.new(user.crypted_password)).to eq(password)
when 'sha1'
user.password = user.password_confirmation = nil
user.send(:write_attribute, :crypted_password, user.sha1(password))
user.save
user.reload
user.crypted_password.should == user.sha1(password)
expect(user.crypted_password).to eq(user.sha1(password))
else
raise "Unknown hashing algorithm: #{algorithm}"
end
@ -49,14 +49,14 @@ 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.where(:login => username).first
user.should_not be_nil
expect(user).to_not be_nil
handle_js_confirm do
page.find(:xpath, "//tr[@id='user-#{user.id}']//img").click
end
get_confirm_text.should == "Warning: this will delete user '#{user.login}', all their actions, contexts, project and notes. Are you sure that you want to continue?"
expect(get_confirm_text).to eq("Warning: this will delete user '#{user.login}', all their actions, contexts, project and notes. Are you sure that you want to continue?")
page.should_not have_css("tr#user-#{user.id}")
expect(page).to_not have_css("tr#user-#{user.id}")
end
Then /^I should see that a user named "([^\"]*)" is not present$/ do |username|

View file

@ -101,48 +101,32 @@ Then /^(?:|I )should see JSON:$/ do |expected_json|
require 'json'
expected = JSON.pretty_generate(JSON.parse(expected_json))
actual = JSON.pretty_generate(JSON.parse(response.body))
expected.should == actual
expect(expected).to eq(actual)
end
Then /^(?:|I )should see "([^"]*)"(?: within "([^"]*)")?$/ do |text, selector|
with_scope(selector) do
if page.respond_to? :should
page.should have_content(text)
else
assert page.has_content?(text)
end
expect(page).to have_content(text)
end
end
Then /^(?:|I )should see \/([^\/]*)\/(?: within "([^"]*)")?$/ do |regexp, selector|
regexp = Regexp.new(regexp)
with_scope(selector) do
if page.respond_to? :should
page.should have_xpath('//*', :text => regexp)
else
assert page.has_xpath?('//*', :text => regexp)
end
expect(page).to have_xpath('//*', :text => regexp)
end
end
Then /^(?:|I )should not see "([^"]*)"(?: within "([^"]*)")?$/ do |text, selector|
with_scope(selector) do
if page.respond_to? :should
page.should have_no_content(text)
else
assert page.has_no_content?(text)
end
expect(page).to have_no_content(text)
end
end
Then /^(?:|I )should not see \/([^\/]*)\/(?: within "([^"]*)")?$/ do |regexp, selector|
regexp = Regexp.new(regexp)
with_scope(selector) do
if page.respond_to? :should
page.should have_no_xpath('//*', :text => regexp)
else
assert page.has_no_xpath?('//*', :text => regexp)
end
expect(page).to have_no_xpath('//*', :text => regexp)
end
end
@ -150,11 +134,7 @@ Then /^the "([^"]*)" field(?: within "([^"]*)")? should contain "([^"]*)"$/ do |
with_scope(selector) do
field = find_field(field)
field_value = (field.tag_name == 'textarea') ? field.text : field.value
if field_value.respond_to? :should
field_value.should =~ /#{value}/
else
assert_match(/#{value}/, field_value)
end
expect(field_value).to match(/#{value}/)
end
end
@ -162,43 +142,27 @@ Then /^the "([^"]*)" field(?: within "([^"]*)")? should not contain "([^"]*)"$/
with_scope(selector) do
field = find_field(field)
field_value = (field.tag_name == 'textarea') ? field.text : field.value
if field_value.respond_to? :should_not
field_value.should_not =~ /#{value}/
else
assert_no_match(/#{value}/, field_value)
end
expect(field_value).to_not match(/#{value}/)
end
end
Then /^the "([^"]*)" checkbox(?: within "([^"]*)")? should be checked$/ do |label, selector|
with_scope(selector) do
field_checked = find_field(label)['checked']
if field_checked.respond_to? :should
field_checked.should be_true
else
assert field_checked
end
expect(field_checked).to be true
end
end
Then /^the "([^"]*)" checkbox(?: within "([^"]*)")? should not be checked$/ do |label, selector|
with_scope(selector) do
field_checked = find_field(label)['checked']
if field_checked.respond_to? :should
field_checked.should be_false
else
assert !field_checked
end
expect(field_checked).to be false
end
end
Then /^(?:|I )should be on (.+)$/ do |page_name|
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
expect(current_path).to eq(path_to(page_name))
end
Then /^(?:|I )should have the following query string:$/ do |expected_pairs|
@ -207,11 +171,7 @@ Then /^(?:|I )should have the following query string:$/ do |expected_pairs|
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
expect(actual_params).to eq(expected_params)
end
Then /^show me the page$/ do

View file

@ -4,10 +4,6 @@ AfterStep('@pause') do
end
Before('@aruba') do
@aruba_timeout_seconds = 5
@aruba_timeout_seconds = 10
# print "\nsetting timeout for aruba to #{@aruba_timeout_seconds}\n"
end
After('@reset_time') do
Timecop.return
end

Some files were not shown because too many files have changed in this diff Show more