all non-cucumber tests are passing

This commit is contained in:
Reinier Balt 2012-04-27 14:22:16 +02:00
parent 13b58f3a10
commit 63175c115b
46 changed files with 248 additions and 505 deletions

16
Gemfile
View file

@ -17,10 +17,6 @@ gem "sanitize", "~>1.2.1"
gem "will_paginate"
gem "acts_as_list", "~>0.1.4"
gem "aasm", "~>2.2.0"
# TODO: gem "rubyjedi-actionwebservice", :require => "actionwebservice"
# gem "rubycas-client", "~>2.2.1"
# gem "ruby-openid", :require => "openid"
# gem "open_id_authentication"
gem 'htmlentities', '~> 4.3.0'
gem "mail"
gem "swf_fu"
@ -60,16 +56,16 @@ gem 'bcrypt-ruby', '~> 3.0.0'
group :development do
if RUBY_VERSION.to_f >= 1.9
# gem "ruby-debug19", :require => 'ruby-debug'
# gem "ruby-debug19", :require => 'ruby-debug'
gem "mongrel", "1.2.0.pre2"
else
# gem "ruby-debug"
# gem "mongrel"
gem "ruby-debug"
gem "mongrel"
end
gem "yard"
end
#
# group :test do
group :test do
# gem "test-unit", "1.2.3"
# gem "flexmock"
# gem "ZenTest", ">=4.0.0"
@ -90,4 +86,4 @@ end
# uncomment to be able to make screenshots from scenarios
#gem "capybara-screenshot"
#gem "launchy"
# end
end

View file

@ -56,13 +56,7 @@ class ContextsController < ApplicationController
end
end
end
# Example XML usage: curl -H 'Accept: application/xml' -H 'Content-Type:
# application/xml'
# -u username:password
# -d '<request><context><name>new context_name</name></context></request>'
# http://our.tracks.host/contexts
#
def create
if params[:format] == 'application/xml' && params['exception']
render_failure "Expected post format is valid xml like so: <context><name>context name</name></context>.", 400
@ -77,7 +71,7 @@ class ContextsController < ApplicationController
end
format.xml do
if @context.new_record?
render_failure @context.errors.to_xml, 409
render_failure @context.errors.to_xml.html_safe, 409
else
head :created, :location => context_url(@context)
end

View file

@ -139,15 +139,9 @@ class ProjectsController < ApplicationController
end
end
# Example XML usage: curl -H 'Accept: application/xml' -H 'Content-Type:
# application/xml'
# -u username:password
# -d '<request><project><name>new project_name</name></project></request>'
# http://our.tracks.host/projects
#
def create
if params[:format] == 'application/xml' && params['exception']
render_failure "Expected post format is valid xml like so: <request><project><name>project name</name></project></request>."
render_failure "Expected post format is valid xml like so: <project><name>project name</name></project>.", 400
return
end
@project = current_user.projects.build(params['project'])
@ -161,7 +155,7 @@ class ProjectsController < ApplicationController
format.js { @down_count = current_user.projects.size }
format.xml do
if @project.new_record?
render_failure @project.errors.full_messages.join(', ')
render_failure @project.errors.to_xml.html_safe, 409
else
head :created, :location => project_url(@project), :text => @project.id
end

View file

@ -161,10 +161,10 @@ class RecurringTodosController < ApplicationController
format.html do
if @saved
notify :notice, t('todos.recurring_deleted_success'), 2.0
notify :notice, t('todos.recurring_deleted_success')
redirect_to :action => 'index'
else
notify :error, t('todos.error_deleting_recurring', :description => @recurring_todo.description), 2.0
notify :error, t('todos.error_deleting_recurring', :description => @recurring_todo.description)
redirect_to :action => 'index'
end
end

View file

@ -106,7 +106,7 @@ class StatsController < ApplicationController
# convert to array and fill in non-existing weeks with 0
@max_weeks = difference_in_weeks(@today, @actions_completion_time.last.completed_at)
@actions_completed_per_week_array = convert_to_weeks_running_array(@actions_completion_time, @max_weeks+1)
# stop the chart after 10 weeks
@count = [10, @max_weeks].min
@ -179,7 +179,7 @@ class StatsController < ApplicationController
# cut off chart at 52 weeks = one year
@count = [52, @max_weeks].min
@actions_open_per_week_array = convert_to_weeks_running_from_today_array(@actions_started, @max_weeks)
@actions_open_per_week_array = convert_to_weeks_running_from_today_array(@actions_started, @max_weeks+1)
@actions_open_per_week_array = cut_off_array(@actions_open_per_week_array, @count)
@max_actions = @actions_open_per_week_array.max
@ -440,7 +440,7 @@ class StatsController < ApplicationController
@pie_height=325
# get the current date wih time set to 0:0
@today = Time.zone.now.beginning_of_day
@today = Time.zone.now.utc.beginning_of_day
# define the number of seconds in a day
@seconds_per_day = 60*60*24
@ -633,38 +633,33 @@ class StatsController < ApplicationController
return selected_todo_ids
end
def convert_to_array(hash, upper_bound)
return Array.new(upper_bound){ |i| hash[i] }
end
# uses the supplied block to determine array of indexes in hash
# the block should return an array of indexes each is added to the hash and summed
def convert_to_hash(records)
def convert_to_array(records, upper_bound)
# use 0 to initialise action count to zero
hash = Hash.new(0)
records.each { |r| (yield r).each { |i| hash[i] += 1} }
return hash
a = Array.new(upper_bound){|i| 0 }
records.each { |r| (yield r).each { |i| a[i] += 1 } }
return a
end
def convert_to_months_from_today_array(records, array_size, date_method_on_todo)
return convert_to_array(convert_to_hash(records){ |r| [difference_in_months(@today, r.send(date_method_on_todo))]}, array_size)
return convert_to_array(records, array_size){ |r| [difference_in_months(@today, r.send(date_method_on_todo))]}
end
def convert_to_days_from_today_array(records, array_size, date_method_on_todo)
return convert_to_array(convert_to_hash(records){ |r| [difference_in_days(@today, r.send(date_method_on_todo))]}, array_size)
return convert_to_array(records, array_size){ |r| [difference_in_days(@today, r.send(date_method_on_todo))]}
end
def convert_to_weeks_from_today_array(records, array_size, date_method_on_todo)
return convert_to_array(convert_to_hash(records) { |r| [difference_in_weeks(@today, r.send(date_method_on_todo))]}, array_size)
return convert_to_array(records, array_size) { |r| [difference_in_weeks(@today, r.send(date_method_on_todo))]}
end
def convert_to_weeks_running_array(records, array_size)
return convert_to_array(convert_to_hash(records) { |r| [difference_in_weeks(r.completed_at, r.created_at)]}, array_size)
return convert_to_array(records, array_size) { |r| [difference_in_weeks(r.completed_at, r.created_at)]}
end
def convert_to_weeks_running_from_today_array(records, array_size)
hash = convert_to_hash(records) { |r| week_indexes_of(r) }
return convert_to_array(hash, array_size)
return convert_to_array(records, array_size) { |r| week_indexes_of(r) }
end
def week_indexes_of(record)
@ -698,14 +693,14 @@ class StatsController < ApplicationController
end
# assumes date1 > date2
# this results in the number of months before the month of date1, not taking days into account, so diff of 31-12 and 1-1 is 1 month!
# this results in the number of months before the month of date1, not taking days into account, so diff of 31-dec and 1-jan is 1 month!
def difference_in_months(date1, date2)
return (date1.year - date2.year)*12 + (date1.month - date2.month)
return (date1.utc.year - date2.utc.year)*12 + (date1.utc.month - date2.utc.month)
end
# assumes date1 > date2
def difference_in_days(date1, date2)
return ((date1.at_midnight-date2.at_midnight)/@seconds_per_day).to_i
return ((date1.utc.at_midnight-date2.utc.at_midnight)/@seconds_per_day).to_i
end
# assumes date1 > date2

View file

@ -11,10 +11,6 @@ class TodosController < ApplicationController
protect_from_forgery :except => :check_deferred
# # these are needed for todo_feed_content. TODO: remove this view stuff from controller
# include ActionView::Helpers::SanitizeHelper
# extend ActionView::Helpers::SanitizeHelper::ClassMethods
def with_feed_query_scope(&block)
unless TodosController.is_feed_request(request)
Todo.send(:where, ['todos.state = ?', 'active']) do
@ -143,8 +139,8 @@ class TodosController < ApplicationController
render :action => 'index'
end
format.xml { render :xml => @todos.to_xml( *to_xml_params ) }
format.rss
format.atom
format.rss { @feed_title, @feed_description = 'Tracks Actions', "Actions for #{current_user.display_name}" }
format.atom { @feed_title, @feed_description = 'Tracks Actions', "Actions for #{current_user.display_name}" }
format.text
format.ics
end
@ -192,7 +188,7 @@ class TodosController < ApplicationController
@todo.project_id = project.id
elsif !(p.project_id.nil? || p.project_id.blank?)
project = current_user.projects.find_by_id(p.project_id)
@todo.errors.add(:project, "unknown") if project.nil?
@todo.errors[:project] << "unknown" if project.nil?
end
if p.context_specified_by_name?
@ -202,33 +198,26 @@ class TodosController < ApplicationController
@todo.context_id = context.id
elsif !(p.context_id.nil? || p.context_id.blank?)
context = current_user.contexts.find_by_id(p.context_id)
@todo.errors.add(:context, "unknown") if context.nil?
@todo.errors[:context] << "unknown" if context.nil?
end
if @todo.errors.empty?
@todo.starred= (params[:new_todo_starred]||"").include? "true" if params[:new_todo_starred]
@todo.add_predecessor_list(predecessor_list)
# Fix for #977 because AASM overrides @state on creation
specified_state = @todo.state
@saved = @todo.save
@todo.update_state_from_project if @saved
else
@saved = false
end
unless (@saved == false) || tag_list.blank?
unless ( !@saved ) || tag_list.blank?
@todo.tag_with(tag_list)
@todo.tags.reload
end
if @saved
unless @todo.uncompleted_predecessors.empty? || @todo.state == 'project_hidden'
@todo.state = 'pending'
end
@todo.save
@todo.block! unless @todo.uncompleted_predecessors.empty? || @todo.state == 'project_hidden'
@saved = @todo.save
end
@todo.reload if @saved
@ -268,7 +257,7 @@ class TodosController < ApplicationController
if @saved
head :created, :location => todo_url(@todo)
else
render :xml => @todo.errors.to_xml, :status => 422
render_failure @todo.errors.to_xml.html_safe, 409
end
end
end
@ -1424,84 +1413,6 @@ class TodosController < ApplicationController
return !( all_list_uniq_ids.length == all_list_count )
end
# def render_text_feed
# lambda do
# render :action => 'index', :layout => false, :content_type => Mime::TEXT
# end
# end
#
# def render_ical_feed
# lambda do
# render :action => 'index', :layout => false, :content_type => Mime::ICS
# end
# end
#
# def self.is_feed_request(req)
# ['rss','atom','txt','ics'].include?(req.parameters[:format])
# end
#
# class FindConditionBuilder
#
# def initialize
# @queries = Array.new
# @params = Array.new
# end
#
# def add(query, param)
# @queries << query
# @params << param
# end
#
# def to_conditions
# [@queries.join(' AND ')] + @params
# end
# end
# def render_rss_feed
# lambda do
# render_rss_feed_for @todos, :feed => todo_feed_options,
# :item => {
# :title => :description,
# :link => lambda { |t| @project_feed.nil? ? context_url(t.context) : project_url(t.project) },
# :guid => lambda { |t| todo_url(t) },
# :description => todo_feed_content
# }
# end
# end
#
# def todo_feed_options
# options = Todo.feed_options(current_user)
# options[:title] = @feed_title
# return options
# end
#
# def todo_feed_content
# # TODO: move view stuff into view, also the includes at the top
# lambda do |i|
# item_notes = i.rendered_notes if i.notes?
# due = "<div>#{t('todos.feeds.due', :date => format_date(i.due))}</div>\n" if i.due?
# done = "<div>#{t('todos.feeds.completed', :date => format_date(i.completed_at))}</div>\n" if i.completed?
# context_link = "<a href=\"#{ context_url(i.context) }\">#{ i.context.name }</a>"
# if i.project_id?
# project_link = "<a href=\"#{ project_url(i.project) }\">#{ i.project.name }</a>"
# else
# project_link = "<em>#{t('common.none')}</em>"
# end
# "#{done||''}#{due||''}#{item_notes||''}\n<div>#{t('common.project')}: #{project_link}</div>\n<div>#{t('common.context')}: #{context_link}</div>"
# end
# end
#
# def render_atom_feed
# lambda do
# render_atom_feed_for @todos, :feed => todo_feed_options,
# :item => {
# :title => :description,
# :link => lambda { |t| context_url(t.context) },
# :description => todo_feed_content,
# :author => lambda { |p| nil }
# }
# end
# end
class TodoCreateParamsHelper
def initialize(params, prefs)

View file

@ -65,7 +65,7 @@ class UsersController < ApplicationController
# POST /users POST /users.xml
def create
if params['exception']
render_failure "Expected post format is valid xml like so: <request><login>username</login><password>abc123</password></request>."
render_failure "Expected post format is valid xml like so: <user><login>username</login><password>abc123</password></user>."
return
end
respond_to do |format|
@ -112,23 +112,21 @@ class UsersController < ApplicationController
return
end
format.xml do
unless User.find_by_id_and_is_admin(session['user_id'], true)
unless current_user && current_user.is_admin
render :text => "401 Unauthorized: Only admin users are allowed access to this function.", :status => 401
return
end
unless check_create_user_params
render_failure "Expected post format is valid xml like so: <request><login>username</login><password>abc123</password></request>."
render_failure "Expected post format is valid xml like so: <user><login>username</login><password>abc123</password></user>.", 400
return
end
user = User.new(params[:request])
if Tracks::Config.auth_schemes.include?('cas') && session[:cas_user]
user.auth_type = "cas" #if they area cas user
end
user.password_confirmation = params[:request][:password]
if user.save
user = User.new(params[:user])
user.password_confirmation = params[:user][:password]
saved = user.save
unless user.new_record?
render :text => t('users.user_created'), :status => 200
else
render_failure user.errors.to_xml
render_failure user.errors.to_xml, 409
end
return
end
@ -144,9 +142,9 @@ class UsersController < ApplicationController
respond_to do |format|
format.html do
if @saved
notify :notice, t('users.successfully_deleted_user', :username => @deleted_user.login), 2.0
notify :notice, t('users.successfully_deleted_user', :username => @deleted_user.login)
else
notify :error, t('users.failed_to_delete_user', :username => @deleted_user.login), 2.0
notify :error, t('users.failed_to_delete_user', :username => @deleted_user.login)
end
redirect_to users_url
end
@ -204,11 +202,11 @@ class UsersController < ApplicationController
end
def check_create_user_params
return false unless params.has_key?(:request)
return false unless params[:request].has_key?(:login)
return false if params[:request][:login].empty?
return false unless params[:request].has_key?(:password)
return false if params[:request][:password].empty?
return false unless params.has_key?(:user)
return false unless params[:user].has_key?(:login)
return false if params[:user][:login].empty?
return false unless params[:user].has_key?(:password)
return false if params[:user][:password].empty?
return true
end

View file

@ -473,6 +473,17 @@ module TodosHelper
return $tracks_tab_index
end
def feed_content_for_todo(todo)
item_notes = todo.notes ? todo.rendered_notes : ''
due = todo.due ? content_tag(:div, t('todos.feeds.due', :date => format_date(todo.due))) : ''
done = todo.completed? ? content_tag(:div, t('todos.feeds.completed', :date => format_date(todo.completed_at))) : ''
context_link = link_to(context_url(todo.context), todo.context.name)
project_link = todo.project.is_a?(NullProject) ? content_tag(:em, t('common.none')) : link_to(project_url(todo.project), todo.project.name)
return "#{done} #{due} #{item_notes}\n" +
content_tag(:div, "#{t('common.project')}: #{project_link}") + "\n" +
content_tag(:div, "#{t('common.context')}: #{context_link}")
end
private
def image_tag_for_star(todo)

View file

@ -246,13 +246,6 @@ class Todo < ActiveRecord::Base
defer! if active? && !date.blank? && date > user.date
end
def self.feed_options(user)
{
:title => 'Tracks Actions',
:description => "Actions for #{user.display_name}"
}
end
def starred?
return has_tag?(STARRED_TAG_NAME)
end

View file

@ -0,0 +1,6 @@
<%
todos_in_context = not_done_todos.select { |t| t.context_id == context.id }
if todos_in_context.length > 0
-%> <%= context.name.upcase %>:
<%= render :partial => "todos/todo", :collection => todos_in_context -%>
<% end -%>

View file

@ -1,7 +0,0 @@
<%
context = text_context
todos_in_context = not_done_todos.select { |t| t.context_id == context.id }
if todos_in_context.length > 0
-%> <%= context.name.upcase %>:
<%= render :partial => "todos/text_todo", :collection => todos_in_context -%>
<% end -%>

View file

@ -1,9 +1,7 @@
<%
<%
require 'htmlentities'
htmlentities = HTMLEntities.new
todo = text_todo
if (todo.starred?)
result_string = " * "
else
@ -23,6 +21,6 @@ end
unless todo.project.nil?
result_string << "(" + todo.project.name + ")"
end
end
-%><%= result_string -%>

View file

@ -0,0 +1,13 @@
atom_feed do |feed|
feed.title(@feed_title)
feed.subtitle(@feed_description)
feed.updated(@todos.last.updated_at)
@todos.each do |todo|
feed.entry(todo) do |entry|
entry.title(h(todo.description))
entry.link(todo.project ? project_url(todo.project) : context_url(todo.context))
entry.content(feed_content_for_todo(todo), :type => :html)
end
end
end

View file

@ -0,0 +1,20 @@
xml.instruct! :xml, :version => "1.0"
xml.rss :version => "2.0" do
xml.channel do
xml.title @feed_title
xml.description @feed_description
xml.link todos_url
xml.language 'en-us'
xml.ttl 40
@todos.each do |todo|
xml.item do
xml.title h(todo.description)
xml.description feed_content_for_todo(todo)
xml.pubDate todo.created_at.to_s(:rfc822)
xml.link todo.project ? project_url(todo.project) : context_url(todo.context)
xml.guid todo_url(todo)
end
end
end
end

View file

@ -1 +1 @@
<%= render :partial => "contexts/text_context", :collection => @contexts, :locals => { :todos => @todos, :not_done_todos => @not_done_todos } %>
<%= render :partial => @contexts, :locals => { :todos => @todos, :not_done_todos => @not_done_todos } %>

View file

@ -1,7 +1,7 @@
<div title="<%= t('users.account_signup') %>" id="signupform" class="form">
<%= form_tag :action=> "create" do %>
<%= error_messages_for 'user' %><br/>
<%= get_list_of_error_messages_for @user %><br/>
<%= render_flash %>
@ -39,7 +39,6 @@
<td><label for="user_auth_type"><%= User.human_attribute_name('auth_type') %>:</label></td>
<td><%= select("user", "auth_type", @auth_types, { :include_blank => false })%></td>
</tr>
<%= observe_field( :user_auth_type, :function => "$('#open_id')[0].style.display = value == 'open_id' ? 'table-row' : 'none'") %>
<%end%>
<tr>
<td></td>

View file

@ -60,9 +60,8 @@ Tracksapp::Application.routes.draw do
match "tickler" => "todos#list_deferred"
match 'review' => "projects#review"
match 'login' => 'users#login'
match 'login_cas' => 'users#login_cas'
match 'logout' => 'users#logout'
match 'login' => 'login#login'
match 'logout' => 'login#logout'
match 'calendar' => "todos#calendar"
match 'stats' => 'stats#index'
match 'done' => "stats#done", :as => 'done_overview'
@ -75,14 +74,15 @@ Tracksapp::Application.routes.draw do
match 'preferences/render_date_format' => "preferences#render_date_format"
resources :contexts do
collection do
post 'order'
get 'done'
end
member do
get 'done_todos'
get 'all_done_todos'
end
collection do
post 'order'
get 'done'
end
resources :todos
end
resources :projects do
@ -97,6 +97,7 @@ Tracksapp::Application.routes.draw do
post 'alphabetize'
post 'actionize'
end
resources :todos
end
resources :todos do

View file

@ -424,7 +424,6 @@ class StatsControllerTest < ActionController::TestCase
assert_equal 2, assigns['count']
end
private
def given_todos_for_stats

View file

@ -135,7 +135,7 @@ class TodosControllerTest < ActionController::TestCase
put :create, :format => "xml", "request" => {
"project_name"=>"Build a working time machine",
"todo"=>{"notes"=>"", "description"=>"Call Warren Buffet to find out how much he makes per day", "due"=>"30/11/2006"}, "tag_list"=>"foo bar" }
assert_response 422
assert_response 409
assert_xml_select "errors" do
assert_xml_select "error", "Context can't be blank"
end

View file

@ -1,60 +1,39 @@
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
require 'contexts_controller'
# Re-raise errors caught by the controller.
class ContextsController; def rescue_action(e) raise e end; end
class ContextXmlApiTest < ActionController::IntegrationTest
fixtures :users, :contexts, :preferences
@@context_name = "@newcontext"
@@valid_postdata = "<request><context><name>#{@@context_name}</name></context></request>"
@@valid_postdata = "<context><name>#{@@context_name}</name></context>"
def setup
assert_test_environment_ok
end
def test_fails_with_invalid_xml_format
# Fails too hard for test to catch
# authenticated_post_xml_to_context_create "<foo></bar>"
# assert_equal 500, @integration_session.status
end
# def test_fails_with_invalid_xml_format
# # Fails too hard for test to catch
# authenticated_post_xml_to_context_create "<foo></bar>"
# assert_response 500
# end
def test_fails_with_invalid_xml_format2
authenticated_post_xml_to_context_create "<request><context></context></request>"
assert_404_invalid_xml
end
def test_xml_simple_param_parsing
authenticated_post_xml_to_context_create
assert @controller.params.has_key?(:request)
assert @controller.params[:request].has_key?(:context)
assert @controller.params[:request][:context].has_key?(:name)
assert_equal @@context_name, @controller.params[:request][:context][:name]
assert @controller.params.has_key?(:context)
assert @controller.params[:context].has_key?(:name)
assert_equal @@context_name, @controller.params[:context][:name]
end
def test_fails_gracefully_with_invalid_xml_format
authenticated_post_xml_to_context_create "<context_name></context_name>"
assert_responses_with_error 'Name context must have a name'
end
def test_fails_with_too_long_name
invalid_with_long_name_postdata = "<request><context><name>foobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoo arfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoo arfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfo barfoobarfoobarfoobarfoobarfoobarfoobar</name></context></request>"
invalid_with_long_name_postdata = "<context><name>foobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoo arfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoo arfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfo barfoobarfoobarfoobarfoobarfoobarfoobar</name></context>"
authenticated_post_xml_to_context_create invalid_with_long_name_postdata
assert_response 409
assert_xml_select 'errors' do
assert_select 'error', 1, 'Name context name must be less than 256 characters'
end
assert_responses_with_error 'Name context name must be less than 256 characters'
end
def test_fails_with_comma_in_name
authenticated_post_xml_to_context_create "<request><context><name>foo,bar</name></context></request>"
assert_response 409
assert_xml_select 'errors' do
assert_select 'error', 1, 'Name cannot contain the comma (\',\') character'
end
end
def test_fails_with_401_if_not_authorized_user
def test_fails_with_401_if_not_authorized_user
authenticated_post_xml_to_context_create @@valid_postdata, 'nobody', 'nohow'
assert_response 401
end
def test_creates_new_context
assert_difference 'Context.count' do
authenticated_post_xml_to_context_create
@ -67,11 +46,7 @@ class ContextXmlApiTest < ActionController::IntegrationTest
private
def authenticated_post_xml_to_context_create(postdata = @@valid_postdata, user = users(:other_user).login, password = 'sesame')
authenticated_post_xml "/contexts", user, password, postdata
authenticated_post_xml "/contexts.xml", user, password, postdata
end
def assert_404_invalid_xml
assert_response_and_body 400, "Expected post format is valid xml like so: <request><context><name>context name</name></context></request>."
end
end

View file

@ -1,28 +1,15 @@
require File.expand_path( File.dirname(__FILE__) + '/../test_helper')
require 'projects_controller'
require 'contexts_controller'
require 'todos_controller'
# Re-raise errors caught by the controller.
class ProjectsController; def rescue_action(e) raise e end; end
class ContextsController; def rescue_action(e) raise e end; end
class TodosController; def rescue_action(e) raise e end; end
class FeedSmokeTest < ActionController::IntegrationTest
fixtures :users, :preferences, :projects, :contexts, :todos, :recurring_todos, :notes
def setup
assert_test_environment_ok
end
def test_last_15_actions_rss
assert_success "/todos.rss?token=#{ users(:admin_user).token }&limit=15"
end
def test_last_15_actions_atom
assert_success "/todos.atom?token=#{ users(:admin_user).token }&limit=15"
end
def test_last_15_actions_txt
assert_success "/todos.txt?token=#{ users(:admin_user).token }&limit=15"
end
@ -34,39 +21,39 @@ class FeedSmokeTest < ActionController::IntegrationTest
def test_all_actions_rss
assert_success "/todos.rss?token=#{ users(:admin_user).token }"
end
def test_all_actions_txt
assert_success "/todos.txt?token=#{ users(:admin_user).token }"
end
def test_all_actions_ical
assert_success "/todos.ics?token=#{ users(:admin_user).token }"
end
def test_all_actions_in_context_rss
assert_success "/contexts/1/todos.rss?token=#{ users(:admin_user).token }"
end
def test_all_actions_in_context_txt
assert_success "/contexts/1/todos.txt?token=#{ users(:admin_user).token }"
end
def test_all_actions_in_context_ical
assert_success "/contexts/1/todos.ics?token=#{ users(:admin_user).token }"
end
def test_all_actions_in_project_rss
assert_success "/projects/1/todos.rss?token=#{ users(:admin_user).token }"
end
def test_all_actions_in_project_txt
assert_success "/projects/1/todos.txt?token=#{ users(:admin_user).token }"
end
def test_all_actions_in_project_ical
assert_success "/projects/1/todos.ics?token=#{ users(:admin_user).token }"
end
def test_all_actions_due_today_or_earlier_rss
assert_success "/todos.rss?token=#{ users(:admin_user).token }&due=0"
end
@ -98,27 +85,27 @@ class FeedSmokeTest < ActionController::IntegrationTest
def test_all_actions_completed_in_last_7_days_txt
assert_success "/todos.txt?token=#{ users(:admin_user).token }&done=7"
end
def test_all_contexts_rss
assert_success "/contexts.rss?token=#{ users(:admin_user).token }"
end
def test_all_contexts_txt
assert_success "/contexts.txt?token=#{ users(:admin_user).token }"
end
def test_all_projects_rss
assert_success "/projects.rss?token=#{ users(:admin_user).token }"
end
def test_all_projects_txt
assert_success "/projects.txt?token=#{ users(:admin_user).token }"
end
def test_calendar_ics
assert_success "/calendar.ics?token=#{ users(:admin_user).token }"
end
def test_all_projects_txt_with_hidden_project
p = projects(:timemachine)
p.hide!

View file

@ -1,145 +0,0 @@
require File.expand_path( File.dirname(__FILE__) + '/../test_helper')
require 'tempfile'
module Tracks
class Config
def self.salt
"change-me"
end
def self.auth_schemes
['database','ldap']
end
end
end
class LdapAuthTest < ActionController::IntegrationTest
fixtures :users
RUN_LDAP_TESTS = ENV['RUN_TRACKS_LDAP_TESTS'] || false
SLAPD_BIN = "/usr/libexec/slapd" #You may need to adjust this
SLAPD_SCHEMA_DIR = "/etc/openldap/schema/" #You may need to adjust this
SLAPD_TEST_PORT = 10389
OUTPUT_DEBUG_INFO = false
begin
require 'net/ldap' #requires ruby-net-ldap gem be installed
require 'simple_ldap_authenticator'
end if RUN_LDAP_TESTS
SimpleLdapAuthenticator.ldap_library = 'net/ldap'
SimpleLdapAuthenticator.servers = %w'localhost'
SimpleLdapAuthenticator.use_ssl = false
SimpleLdapAuthenticator.login_format = 'cn=%s,dc=lukemelia,dc=com'
SimpleLdapAuthenticator.port = 10389
SimpleLdapAuthenticator.logger = RAILS_DEFAULT_LOGGER
def setup
assert_equal "test", ENV['RAILS_ENV']
assert_equal "change-me", Tracks::Config.salt
if RUN_LDAP_TESTS
setup_ldap_server_conf
start_ldap_server
end
end
def teardown
stop_ldap_server if RUN_LDAP_TESTS
end
def test_authenticate_against_ldap
add_ldap_user_to_ldap_repository
assert SimpleLdapAuthenticator.valid?('john', 'deere')
user = User.authenticate('john', 'deere')
assert_not_nil(user)
assert_equal user.login, 'john'
end
private :test_authenticate_against_ldap unless RUN_LDAP_TESTS
def setup_ldap_server_conf
@slapd_conf = create_slapd_conf()
open(@slapd_conf.path) { |f| f.read }
unless File.exist?(SLAPD_BIN)
assert false, "slapd could not be found at #{SLAPD_BIN}. Adjust the path in #{__FILE__}"
end
end
def start_ldap_server
t = Thread.new(@slapd_conf.path) do |slapd_conf_path|
puts "starting slapd..." if OUTPUT_DEBUG_INFO
run_cmd %Q{/usr/libexec/slapd -f #{slapd_conf_path} -h "ldap://127.0.0.1:10389/" -d0}
end
sleep(2)
run_cmd %Q{ldapsearch -H "ldap://127.0.0.1:10389/" -x -b '' -s base '(objectclass=*)' namingContexts}
end
def add_ldap_user_to_ldap_repository
ldif_file = create_ldif()
run_cmd %Q{ldapadd -H "ldap://127.0.0.1:10389/" -f #{ldif_file.path} -cxv -D "cn=Manager,dc=lukemelia,dc=com" -w secret}
puts `cat #{ldif_file.path}` if OUTPUT_DEBUG_INFO
end
def stop_ldap_server
pid = open(get_pid_file_path(@slapd_conf)) { |f| f.read }
run_cmd "kill -TERM #{pid}"
end
def create_slapd_conf
slapd_conf = Tempfile.new("slapd.conf")
slapd_conf.path
data_dir = slapd_conf.path + '-data'
pid_file = get_pid_file_path(slapd_conf)
Dir.mkdir(data_dir)
encrypted_password = `slappasswd -s secret`
open(slapd_conf.path, 'w') do |f|
f.puts %Q{include #{SLAPD_SCHEMA_DIR}core.schema
pidfile #{pid_file}
database ldbm
suffix "dc=lukemelia,dc=com"
rootdn "cn=Manager,dc=lukemelia,dc=com"
rootpw #{encrypted_password}
directory #{data_dir}
access to *
by self write
by users read
by anonymous auth
}
end
puts `cat #{slapd_conf.path}` if OUTPUT_DEBUG_INFO
slapd_conf
end
def create_ldif
ldif_file = Tempfile.new("ldap_user.ldif")
encrypted_password = `slappasswd -s deere`
open(ldif_file.path, 'w') do |f|
f.puts %Q{dn: dc=lukemelia,dc=com
objectclass: dcObject
objectclass: organization
o: Luke Melia DotCom
dc: lukemelia
dn: cn=john,dc=lukemelia,dc=com
cn: john
sn: john
objectclass: person
userPassword: #{encrypted_password}
}
end
ldif_file
end
def run_cmd(cmd)
puts cmd if OUTPUT_DEBUG_INFO
cmd_out = `#{cmd}`
puts cmd_out if OUTPUT_DEBUG_INFO
end
def get_pid_file_path(tempfile)
tempfile.path + '.pid'
end
end

View file

@ -1,21 +1,11 @@
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
require 'projects_controller'
# Re-raise errors caught by the controller.
class ProjectsController; def rescue_action(e) raise e end; end
class ProjectXmlApiTest < ActionController::IntegrationTest
fixtures :users, :projects
@@project_name = "My New Project"
@@valid_postdata = "<request><project><name>#{@@project_name}</name></project></request>"
def setup
assert_test_environment_ok
end
@@valid_postdata = "<project><name>#{@@project_name}</name></project>"
def test_retrieve_project
authenticated_get_xml "/projects/1", users(:admin_user).login, 'abracadabra', {}
authenticated_get_xml "/projects/1.xml", users(:admin_user).login, 'abracadabra', {}
assert_tag :tag => "project"
assert_tag :tag => "project", :child => {:tag => "not_done" }
assert_tag :tag => "project", :child => {:tag => "deferred" }
@ -32,30 +22,29 @@ class ProjectXmlApiTest < ActionController::IntegrationTest
def test_fails_with_invalid_xml_format2
authenticated_post_xml_to_project_create "<request><project></project></request>"
assert_404_invalid_xml
assert_responses_with_error 'Name project must have a name'
end
def test_xml_simple_param_parsing
authenticated_post_xml_to_project_create
assert @controller.params.has_key?(:request)
assert @controller.params[:request].has_key?(:project)
assert @controller.params[:request][:project].has_key?(:name)
assert_equal @@project_name, @controller.params[:request][:project][:name]
assert @controller.params.has_key?(:project)
assert @controller.params[:project].has_key?(:name)
assert_equal @@project_name, @controller.params[:project][:name]
end
def test_fails_with_401_if_not_authorized_user
def test_fails_with_401_if_not_authorized_user
authenticated_post_xml_to_project_create @@valid_postdata, 'nobody', 'nohow'
assert_response 401
end
def test_fails_with_too_long_name
invalid_with_long_name_postdata = "<request><project><name>foobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoo arfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoo arfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfo barfoobarfoobarfoobarfoobarfoobarfoobar</name></project></request>"
invalid_with_long_name_postdata = "<project><name>foobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoo arfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoo arfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfo barfoobarfoobarfoobarfoobarfoobarfoobar</name></project>"
authenticated_post_xml_to_project_create invalid_with_long_name_postdata
assert_response_and_body 404, "Name project name must be less than 256 characters"
assert_responses_with_error 'Name context name must be less than 256 characters'
end
def test_fails_with_comma_in_name
authenticated_post_xml_to_project_create "<request><project><name>foo,bar</name></project></request>"
authenticated_post_xml_to_project_create "<project><name>foo,bar</name></project>"
assert_response :created
project1 = Project.find_by_name("foo,bar")
assert_not_nil project1, "expected project 'foo,bar' to be created"
@ -73,11 +62,11 @@ class ProjectXmlApiTest < ActionController::IntegrationTest
private
def authenticated_post_xml_to_project_create(postdata = @@valid_postdata, user = users(:other_user).login, password = 'sesame')
authenticated_post_xml "/projects", user, password, postdata
authenticated_post_xml "/projects.xml", user, password, postdata
end
def assert_404_invalid_xml
assert_response_and_body 404, "Expected post format is valid xml like so: <request><project><name>project name</name></project></request>."
assert_response_and_body 404, "Expected post format is valid xml like so: <project><name>project name</name></project>."
end
end

View file

@ -1,9 +1,6 @@
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
require 'todos_controller'
require 'recurring_todos_controller'
class RecurringTodosTest < ActionController::IntegrationTest
fixtures :users, :preferences, :projects, :contexts, :todos, :tags, :taggings, :recurring_todos
def logs_in_as(user,plain_pass)
@user = user
@ -16,22 +13,21 @@ class RecurringTodosTest < ActionController::IntegrationTest
assert_template "todos/index"
end
def test_deleting_recurring_todo_clears_reference_from_related_todos
logs_in_as(users(:admin_user), 'abracadabra')
rt = RecurringTodo.find(1)
assert !rt.nil? # given there is a recurring todo
assert rt.todos.size, 1 # and it has one todos referencing it
assert_equal 1, rt.todos.size # and it has one todo referencing it
# when I toggle the todo complete
todo = Todo.find_by_recurring_todo_id(1)
post "/todos/toggle_check/#{todo.id}", :_source_view => 'todo'
put "/todos/#{todo.id}/toggle_check", :_source_view => 'todo'
todo.reload
assert todo.completed?
rt.reload # then there should be two todos referencing
assert rt.todos.size, 2
assert_equal 2, rt.todos.size
todo2 = Todo.find(:first, :conditions => {:recurring_todo_id => rt.id, :state => 'active'})
assert_not_equal todo2.id, todo.id # and the todos should be different

View file

@ -1,11 +1,6 @@
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
class StoriesTest < ActionController::IntegrationTest
fixtures :users, :preferences, :projects, :contexts, :todos, :recurring_todos, :notes
def setup
assert_test_environment_ok
end
# ####################################################
# Testing login and signup by different kinds of users
@ -13,7 +8,7 @@ class StoriesTest < ActionController::IntegrationTest
def test_signup_new_user_by_admin
admin = new_session_as(:admin_user,"abracadabra")
admin.goes_to_signup
admin.signs_up_with(:user => {:login => "newbie",
admin.signs_up_with(:user => {:login => "newbie",
:password => "newbiepass",
:password_confirmation => "newbiepass"})
end
@ -31,8 +26,8 @@ class StoriesTest < ActionController::IntegrationTest
def logs_in_as(user,plain_pass)
@user = user
post "/login", :user_login => @user.login,
:user_password => plain_pass,
post "/login", :user_login => @user.login,
:user_password => plain_pass,
:user_noexpiry => 'n'
assert_response :redirect
follow_redirect!

View file

@ -1,19 +1,15 @@
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
require 'todos_controller'
class TodoXmlApiTest < ActionController::IntegrationTest
fixtures :users, :contexts, :preferences, :todos, :projects
@@valid_postdata = "<todo><description>this will succeed</description><context_id type='integer'>10</context_id><project_id type='integer'>4</project_id></todo>"
def setup
assert_test_environment_ok
@user = users(:admin_user)
@password = 'abracadabra'
end
def test_get_tickler_succeeds
authenticated_get_xml "/tickler", @user.login, @password, {}
authenticated_get_xml "/tickler.xml", @user.login, @password, {}
assert_response 200
end
@ -21,18 +17,18 @@ class TodoXmlApiTest < ActionController::IntegrationTest
get '/tickler.xml', {}, {}
assert_response 401
get "/tickler", {}, {'AUTHORIZATION' => "Basic " + Base64.encode64("wrong:wrong"),'ACCEPT' => 'application/xml'}
get "/tickler.xml", {}, {'HTT_AUTHORIZATION' => "Basic " + Base64.encode64("wrong:wrong"),'ACCEPT' => 'application/xml'}
assert_response 401
end
def test_get_tickler_returns_all_deferred_and_pending_todos
number = @user.todos.deferred.count + @user.todos.pending.count
authenticated_get_xml "/tickler", @user.login, @password, {}
authenticated_get_xml "/tickler.xml", @user.login, @password, {}
assert_tag :tag => "todos", :children => { :count => number }
end
def test_get_tickler_omits_user_id
authenticated_get_xml "/tickler", @user.login, @password, {}
authenticated_get_xml "/tickler.xml", @user.login, @password, {}
assert_no_tag :tag => "user_id"
end
@ -225,7 +221,7 @@ class TodoXmlApiTest < ActionController::IntegrationTest
assert_not_nil todo
assert_not_nil todo.project
assert_equal projects(:timemachine).name, todo.project.name
assert 1, @user.projects.all(:conditions => ["projects.name = ?", projects(:timemachine).name]).count # no duplication of project
assert_equal 1, @user.projects.where("projects.name" => projects(:timemachine).name).count # no duplication of project
end
def test_post_create_todo_with_wrong_project_and_context_id
@ -235,7 +231,7 @@ class TodoXmlApiTest < ActionController::IntegrationTest
<context_id type='integer'>-16</context_id>
<project_id type='integer'>-11</project_id>
</todo>"
assert_response 422
assert_response 409
assert_xml_select 'errors' do
assert_select 'error', 2
end
@ -249,7 +245,7 @@ class TodoXmlApiTest < ActionController::IntegrationTest
private
def authenticated_post_xml_to_todo_create(postdata = @@valid_postdata, user = @user.login, password = @password)
authenticated_post_xml "/todos", user, password, postdata
authenticated_post_xml "/todos.xml", user, password, postdata
end
end

View file

@ -1,18 +1,9 @@
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
require 'users_controller'
# Re-raise errors caught by the controller.
class UsersController; def rescue_action(e) raise e end; end
class UsersXmlApiTest < ActionController::IntegrationTest
fixtures :users
@@foobar_postdata = "<request><login>foo</login><password>bar</password></request>"
@@johnny_postdata = "<request><login>johnny</login><password>barracuda</password></request>"
def setup
assert_test_environment_ok
end
@@foobar_postdata = "<user><login>foo</login><password>bar</password></user>"
@@johnny_postdata = "<user><login>johnny</login><password>barracuda</password></user>"
def test_fails_with_401_if_not_authorized_user
authenticated_post_xml_to_user_create @@foobar_postdata, 'nobody', 'nohow'
@ -26,7 +17,7 @@ class UsersXmlApiTest < ActionController::IntegrationTest
def test_content_type_must_be_xml
authenticated_post_xml_to_user_create @@foobar_postdata, users(:admin_user).login, 'abracadabra', {'CONTENT_TYPE' => "application/x-www-form-urlencoded"}
assert_404_invalid_xml
assert_response 400, "Expected response 400"
end
# Fails too hard for test to catch
@ -36,43 +27,43 @@ class UsersXmlApiTest < ActionController::IntegrationTest
# end
def test_fails_with_invalid_xml_format2
authenticated_post_xml_to_user_create "<request><username>foo</username></request>"
assert_404_invalid_xml
authenticated_post_xml_to_user_create "<username>foo</username>"
assert_response_and_body 400, "Expected post format is valid xml like so: <user><login>username</login><password>abc123</password></user>."
end
def test_xml_simple_param_parsing
authenticated_post_xml_to_user_create
assert @controller.params.has_key?(:request)
assert @controller.params[:request].has_key?(:login)
assert @controller.params[:request].has_key?(:password)
assert_equal 'foo', @controller.params[:request][:login]
assert_equal 'bar', @controller.params[:request][:password]
assert @controller.params.has_key?(:user)
assert @controller.params['user'].has_key?(:login)
assert @controller.params['user'].has_key?(:password)
assert_equal 'foo', @controller.params['user'][:login]
assert_equal 'bar', @controller.params['user'][:password]
end
def test_fails_with_too_short_password
authenticated_post_xml_to_user_create
assert_response_and_body 404, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<errors>\n <error>Password is too short (minimum is 5 characters)</error>\n</errors>\n"
assert_responses_with_error "Password is too short (minimum is 5 characters"
end
def test_fails_with_nonunique_login
existing_login = users(:other_user).login
authenticated_post_xml_to_user_create "<request><login>#{existing_login}</login><password>barracuda</password></request>"
assert_response_and_body 404, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<errors>\n <error>Login has already been taken</error>\n</errors>\n"
authenticated_post_xml_to_user_create "<user><login>#{existing_login}</login><password>barracuda</password></user>"
assert_responses_with_error "Login has already been taken"
end
def test_creates_new_user
initial_count = User.count
authenticated_post_xml_to_user_create @@johnny_postdata
assert_response_and_body 200, "User created."
assert_equal initial_count + 1, User.count
assert_difference 'User.count' do
authenticated_post_xml_to_user_create @@johnny_postdata
assert_response_and_body 200, "User created."
end
johnny1 = User.find_by_login('johnny')
assert_not_nil johnny1, "expected user johnny to be created"
johnny2 = User.authenticate('johnny','barracuda')
assert_not_nil johnny2, "expected user johnny to be created"
assert_not_nil johnny2, "expected user johnny to be authenticated"
end
def test_fails_with_get_verb
authenticated_get_xml "/users", users(:admin_user).login, 'abracadabra', {}
authenticated_get_xml "/users.xml", users(:admin_user).login, 'abracadabra', {}
end
def test_get_users_as_xml
@ -93,15 +84,10 @@ class UsersXmlApiTest < ActionController::IntegrationTest
private
def basic_auth_headers(username = users(:admin_user).login, password = 'abracadabra')
{'AUTHORIZATION' => "Basic " + Base64.encode64("#{username}:#{password}") }
{'HTTP_AUTHORIZATION' => "Basic " + Base64.encode64("#{username}:#{password}") }
end
def authenticated_post_xml_to_user_create(postdata = @@foobar_postdata, user = users(:admin_user).login, password = 'abracadabra', headers = {})
authenticated_post_xml "/users", user, password, postdata, headers
authenticated_post_xml "/users.xml", user, password, postdata, headers
end
def assert_404_invalid_xml
assert_response_and_body 404, "Expected post format is valid xml like so: <request><login>username</login><password>abc123</password></request>."
end
end

View file

@ -36,6 +36,14 @@ class ActiveSupport::TestCase
assert_equal date1.strftime("%d-%m-%y"), date2.strftime("%d-%m-%y")
end
def xml_document
@xml_document ||= HTML::Document.new(@response.body, false, true)
end
def assert_xml_select(*args, &block)
@html_document = xml_document
assert_select(*args, &block)
end
end
class ActionController::TestCase
@ -68,10 +76,6 @@ class ActionController::TestCase
private
def xml_document
@xml_document ||= HTML::Document.new(@response.body, false, true)
end
def get_model_class
@controller.class.to_s.tableize.split("_")[0].camelcase.singularize #don't ask... converts ContextsController to Context
end
@ -80,4 +84,49 @@ class ActionController::TestCase
eval("#{get_model_class}.count")
end
end
class ActionController::IntegrationTest
def authenticated_post_xml(url, username, password, parameters, headers = {})
post url, parameters,
{ 'HTTP_AUTHORIZATION' => "Basic " + Base64.encode64("#{username}:#{password}"),
'ACCEPT' => 'application/xml',
'CONTENT_TYPE' => 'application/xml'
}.merge(headers)
end
def authenticated_get_xml(url, username, password, parameters, headers = {})
get url, parameters,
{ 'HTTP_AUTHORIZATION' => "Basic " + Base64.encode64("#{username}:#{password}"),
'ACCEPT' => 'application/xml',
'CONTENT_TYPE' => 'application/xml'
}.merge(headers)
end
def assert_response_and_body(type, body, message = nil)
assert_equal body, @response.body, message
assert_response type, message
end
def assert_response_and_body_matches(type, body_regex, message = nil)
assert_response type, message
assert_match body_regex, @response.body, message
end
def assert_401_unauthorized
assert_response_and_body 401, "401 Unauthorized: You are not authorized to interact with Tracks."
end
def assert_401_unauthorized_admin
assert_response_and_body 401, "401 Unauthorized: Only admin users are allowed access to this function."
end
def assert_responses_with_error(error_msg)
assert_response 409
assert_xml_select 'errors' do
assert_select 'error', 1, error_msg
end
end
end

View file

@ -120,12 +120,6 @@ class TodoTest < ActiveSupport::TestCase
assert_equal :deferred, todo.aasm_current_state
end
def test_feed_options
opts = Todo.feed_options(users(:admin_user))
assert_equal 'Tracks Actions', opts[:title], 'Unexpected value for :title key of feed_options'
assert_equal 'Actions for Admin Schmadmin', opts[:description], 'Unexpected value for :description key of feed_options'
end
def test_toggle_completion
t = @not_completed1
assert_equal :active, t.aasm_current_state