Made TodosController more RESTful and use it to fulfill all feeds, eliminating the need for the FeedController and it's helper and views. Also added an ATOM feed (not linked in the UI anywhere, just substitute .atom for .rss).

I also ran rcov on unit tests and added tests to improve test coverage, uncovering a couple of bugs along the way.

git-svn-id: http://www.rousette.org.uk/svn/tracks-repos/trunk@476 a4c988fc-2ded-0310-b66e-134b36920a42
This commit is contained in:
lukemelia 2007-03-18 00:38:05 +00:00
parent 84357b67d5
commit 106d5ee448
38 changed files with 1007 additions and 680 deletions

View file

@ -2,7 +2,7 @@
<%
def today
Time.now.utc.to_s(:db)
Time.now.utc.to_date.to_time.to_s(:db)
end
%>

View file

@ -2,19 +2,19 @@
<%
def today
Time.now.utc.to_s(:db)
Time.now.utc.to_date.to_time.to_s(:db)
end
def next_week
1.week.from_now.utc.to_s(:db)
1.week.from_now.to_date.to_time.utc.to_s(:db)
end
def last_week
1.week.ago.utc.to_s(:db)
1.week.ago.utc.to_date.to_time.to_s(:db)
end
def two_weeks_hence
2.week.from_now.utc.to_s(:db)
2.weeks.from_now.utc.to_date.to_time.to_s(:db)
end
%>
@ -136,7 +136,7 @@ end
state: completed
created_at: <%= today %>
due: <%= two_weeks_hence %>
completed_at: <%= today %>
completed_at: <%= last_week %>
user_id: 1
11:
@ -197,7 +197,7 @@ end
created_at: <%= today %>
due: ~
completed_at: ~
show_from: <%= next_week %>
show_from: <%= today %>
user_id: 1
16:

View file

@ -47,19 +47,23 @@ class ContextsControllerTest < TodoContainerControllerTestBase
#puts @response.body
assert_xml_select 'rss[version="2.0"]' do
assert_xml_select 'channel' do
assert_xml_select '>title', 'Tracks Contexts'
assert_xml_select '>description', "Lists all the contexts for #{users(:admin_user).display_name}."
assert_xml_select 'language', 'en-us'
assert_xml_select 'ttl', '40'
assert_select 'channel' do
assert_select '>title', 'Tracks Contexts'
assert_select '>description', "Lists all the contexts for #{users(:admin_user).display_name}"
assert_select 'language', 'en-us'
assert_select 'ttl', '40'
end
assert_xml_select 'item', 9 do
assert_xml_select 'title', /.+/
assert_xml_select 'description', /&lt;p&gt;\d+ actions. Context is (active|hidden). &lt;\/p&gt;/
%w(guid link).each do |node|
assert_xml_select node, /http:\/\/test.host\/contexts\/.+/
assert_select 'item', 9 do
assert_select 'title', /.+/
assert_select 'description' do
assert_select_encoded do
assert_select 'p', /\d+&nbsp;actions. Context is (Active|Hidden)./
end
end
assert_xml_select 'pubDate', /(#{contexts(:agenda).created_at.to_s(:rfc822)}|#{contexts(:library).created_at.to_s(:rfc822)})/
%w(guid link).each do |node|
assert_select node, /http:\/\/test.host\/contexts\/.+/
end
assert_select 'pubDate', /(#{contexts(:agenda).created_at.to_s(:rfc822)}|#{contexts(:library).created_at.to_s(:rfc822)})/
end
end
end
@ -89,12 +93,16 @@ class ContextsControllerTest < TodoContainerControllerTestBase
#puts @response.body
assert_xml_select 'feed[xmlns="http://www.w3.org/2005/Atom"]' do
assert_xml_select '>title', 'Tracks Contexts'
assert_xml_select '>subtitle', "Lists all the contexts for #{users(:admin_user).display_name}."
assert_xml_select 'entry', 3 do
assert_xml_select 'title', /.+/
assert_xml_select 'content[type="html"]', /&lt;p&gt;\d+ actions. Context is (active|hidden). &lt;\/p&gt;/
assert_xml_select 'published', /(#{contexts(:agenda).created_at.to_s(:rfc822)}|#{contexts(:library).created_at.to_s(:rfc822)})/
assert_select '>title', 'Tracks Contexts'
assert_select '>subtitle', "Lists all the contexts for #{users(:admin_user).display_name}"
assert_select 'entry', 9 do
assert_select 'title', /.+/
assert_select 'content[type="html"]' do
assert_select_encoded do
assert_select 'p', /\d+&nbsp;actions. Context is (Active|Hidden)./
end
end
assert_select 'published', /(#{contexts(:agenda).created_at.xmlschema}|#{contexts(:library).created_at.xmlschema})/
end
end
end

View file

@ -1,17 +0,0 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'feed_controller'
# Re-raise errors caught by the controller.
class FeedController; def rescue_action(e) raise e end; end
class FeedControllerTest < Test::Unit::TestCase
def setup
@controller = FeedController.new
request, response = ActionController::TestRequest.new, ActionController::TestResponse.new
end
# Replace this with your real tests.
def test_truth
assert true
end
end

View file

@ -101,19 +101,23 @@ class ProjectsControllerTest < TodoContainerControllerTestBase
#puts @response.body
assert_xml_select 'rss[version="2.0"]' do
assert_xml_select 'channel' do
assert_xml_select '>title', 'Tracks Projects'
assert_xml_select '>description', "Lists all the projects for #{users(:admin_user).display_name}."
assert_xml_select 'language', 'en-us'
assert_xml_select 'ttl', '40'
assert_select 'channel' do
assert_select '>title', 'Tracks Projects'
assert_select '>description', "Lists all the projects for #{users(:admin_user).display_name}"
assert_select 'language', 'en-us'
assert_select 'ttl', '40'
end
assert_xml_select 'item', 3 do
assert_xml_select 'title', /.+/
assert_xml_select 'description', /&lt;p&gt;\d+ actions. Project is (active|hidden|completed). &lt;\/p&gt;/
%w(guid link).each do |node|
assert_xml_select node, /http:\/\/test.host\/projects\/.+/
assert_select 'item', 3 do
assert_select 'title', /.+/
assert_select 'description' do
assert_select_encoded do
assert_select 'p', /^\d+&nbsp;actions\. Project is (active|hidden|completed)\.$/
end
end
assert_xml_select 'pubDate', /(#{projects(:timemachine).updated_at.to_s(:rfc822)}|#{projects(:moremoney).updated_at.to_s(:rfc822)}})/
%w(guid link).each do |node|
assert_select node, /http:\/\/test.host\/projects\/.+/
end
assert_select 'pubDate', /(#{projects(:timemachine).updated_at.to_s(:rfc822)}|#{projects(:moremoney).updated_at.to_s(:rfc822)})/
end
end
end
@ -143,12 +147,16 @@ class ProjectsControllerTest < TodoContainerControllerTestBase
#puts @response.body
assert_xml_select 'feed[xmlns="http://www.w3.org/2005/Atom"]' do
assert_xml_select '>title', 'Tracks Projects'
assert_xml_select '>subtitle', "Lists all the projects for #{users(:admin_user).display_name}."
assert_xml_select 'entry', 3 do
assert_xml_select 'title', /.+/
assert_xml_select 'content[type="html"]', /&lt;p&gt;\d+ actions. Project is (active|hidden|completed). &lt;\/p&gt;/
assert_xml_select 'published', /(#{projects(:timemachine).updated_at.to_s(:rfc822)}|#{projects(:moremoney).updated_at.to_s(:rfc822)}})/
assert_select '>title', 'Tracks Projects'
assert_select '>subtitle', "Lists all the projects for #{users(:admin_user).display_name}"
assert_select 'entry', 3 do
assert_select 'title', /.+/
assert_select 'content[type="html"]' do
assert_select_encoded do
assert_select 'p', /\d+&nbsp;actions. Project is (active|hidden|completed)./
end
end
assert_select 'published', /(#{projects(:timemachine).updated_at.xmlschema}|#{projects(:moremoney).updated_at.xmlschema})/
end
end
end

View file

@ -123,6 +123,116 @@ class TodosControllerTest < Test::Unit::TestCase
assert_response :success
assert_equal 3, @tagged
end
def test_rss_feed_content
@request.session['user_id'] = users(:admin_user).id
get :index, { :format => "rss" }
assert_equal 'application/rss+xml; charset=utf-8', @response.headers["Content-Type"]
#puts @response.body
assert_xml_select 'rss[version="2.0"]' do
assert_select 'channel' do
assert_select '>title', 'Tracks Actions'
assert_select '>description', "Actions for #{users(:admin_user).display_name}"
assert_select 'language', 'en-us'
assert_select 'ttl', '40'
assert_select 'item', 10 do
assert_select 'title', /.+/
assert_select 'description', /.*/
%w(guid link).each do |node|
assert_select node, /http:\/\/test.host\/contexts\/.+/
end
assert_select 'pubDate', /(#{projects(:timemachine).updated_at.to_s(:rfc822)}|#{projects(:moremoney).updated_at.to_s(:rfc822)})/
end
end
end
end
def test_rss_feed_not_accessible_to_anonymous_user_without_token
@request.session['user_id'] = nil
get :index, { :format => "rss" }
assert_response 401
end
def test_rss_feed_not_accessible_to_anonymous_user_with_invalid_token
@request.session['user_id'] = nil
get :index, { :format => "rss", :token => 'foo' }
assert_response 401
end
def test_rss_feed_accessible_to_anonymous_user_with_valid_token
@request.session['user_id'] = nil
get :index, { :format => "rss", :token => users(:admin_user).word }
assert_response :ok
end
def test_atom_feed_content
@request.session['user_id'] = users(:admin_user).id
get :index, { :format => "atom" }
assert_equal 'application/atom+xml; charset=utf-8', @response.headers["Content-Type"]
#puts @response.body
assert_xml_select 'feed[xmlns="http://www.w3.org/2005/Atom"]' do
assert_xml_select '>title', 'Tracks Actions'
assert_xml_select '>subtitle', "Actions for #{users(:admin_user).display_name}"
assert_xml_select 'entry', 10 do
assert_xml_select 'title', /.+/
assert_xml_select 'content[type="html"]', /.*/
assert_xml_select 'published', /(#{projects(:timemachine).updated_at.xmlschema}|#{projects(:moremoney).updated_at.xmlschema})/
end
end
end
def test_atom_feed_not_accessible_to_anonymous_user_without_token
@request.session['user_id'] = nil
get :index, { :format => "atom" }
assert_response 401
end
def test_atom_feed_not_accessible_to_anonymous_user_with_invalid_token
@request.session['user_id'] = nil
get :index, { :format => "atom", :token => 'foo' }
assert_response 401
end
def test_atom_feed_accessible_to_anonymous_user_with_valid_token
@request.session['user_id'] = nil
get :index, { :format => "atom", :token => users(:admin_user).word }
assert_response :ok
end
def test_text_feed_content
@request.session['user_id'] = users(:admin_user).id
get :index, { :format => "txt" }
assert_equal 'text/plain; charset=utf-8', @response.headers["Content-Type"]
assert !(/&nbsp;/.match(@response.body))
#puts @response.body
end
def test_text_feed_not_accessible_to_anonymous_user_without_token
@request.session['user_id'] = nil
get :index, { :format => "txt" }
assert_response 401
end
def test_text_feed_not_accessible_to_anonymous_user_with_invalid_token
@request.session['user_id'] = nil
get :index, { :format => "txt", :token => 'foo' }
assert_response 401
end
def test_text_feed_accessible_to_anonymous_user_with_valid_token
@request.session['user_id'] = nil
get :index, { :format => "txt", :token => users(:admin_user).word }
assert_response :ok
end
def test_ical_feed_content
@request.session['user_id'] = users(:admin_user).id
get :index, { :format => "ics" }
assert_equal 'text/calendar; charset=utf-8', @response.headers["Content-Type"]
assert !(/&nbsp;/.match(@response.body))
#puts @response.body
end
end

View file

@ -40,18 +40,32 @@ class ContextXmlApiTest < ActionController::IntegrationTest
def test_fails_with_too_long_name
invalid_with_long_name_postdata = "<request><context><name>foobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoo arfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoo arfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfoobarfo barfoobarfoobarfoobarfoobarfoobarfoobar</name></context></request>"
authenticated_post_xml_to_context_create invalid_with_long_name_postdata
assert_response_and_body 404, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<errors>\n <error>Name context name must be less than 256 characters</error>\n</errors>\n"
assert_response 404
assert_xml_select 'errors' do
assert_select 'error', 1, 'Name context name must be less than 256 characters'
end
end
def test_fails_with_slash_in_name
authenticated_post_xml_to_context_create "<request><context><name>foo/bar</name></context></request>"
assert_response_and_body 404, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<errors>\n <error>Name cannot contain the slash ('/') character</error>\n</errors>\n"
assert_response 404
assert_xml_select 'errors' do
assert_select 'error', 1, 'Name cannot contain the slash (\'/\') character'
end
end
def test_creates_new_context
initial_count = Context.count
authenticated_post_xml_to_context_create
assert_response_and_body_matches 200, %r|^<\?xml version="1.0" encoding="UTF-8"\?>\n<context>\n <created-at type=\"datetime\">\d{4}+-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z</created-at>\n <hide type="integer">0</hide>\n <id type="integer">\d+</id>\n <name>#{@@context_name}</name>\n <position type="integer">3</position>\n <updated-at type=\"datetime\">\d{4}+-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z</updated-at>\n</context>\n$|
assert_response 200
assert_xml_select 'context' do
assert_select 'created-at', /\d{4}+-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z/
assert_select 'hide', 'false'
assert_select 'id', /\d+/
assert_select 'name', @@context_name
assert_select 'position', '3'
assert_select 'updated-at', /\d{4}+-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z/
end
assert_equal initial_count + 1, Context.count
context1 = Context.find_by_name(@@context_name)
assert_not_nil context1, "expected context '#{@@context_name}' to be created"

View file

@ -1,7 +1,7 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'projects_controller'
require 'contexts_controller'
require 'feed_controller'
require 'todos_controller'
# Re-raise errors caught by the controller.
class ProjectsController; def rescue_action(e) raise e end; end
@ -16,59 +16,87 @@ class FeedSmokeTest < ActionController::IntegrationTest
end
def test_last_15_actions_rss
assert_success "/feed/rss/admin/#{ users(:admin_user).word }?limit=15"
assert_success "/todos.rss?token=#{ users(:admin_user).word }&limit=15"
end
def test_last_15_actions_atom
assert_success "/todos.atom?token=#{ users(:admin_user).word }&limit=15"
end
def test_last_15_actions_txt
assert_success "/feed/text/admin/#{ users(:admin_user).word }?limit=15"
assert_success "/todos.txt?token=#{ users(:admin_user).word }&limit=15"
end
def test_last_15_actions_ical
assert_success "/feed/ical/admin/#{ users(:admin_user).word }?limit=15"
assert_success "/todos.ics?token=#{ users(:admin_user).word }&limit=15"
end
def test_all_actions_rss
assert_success "/feed/rss/admin/#{ users(:admin_user).word }"
assert_success "/todos.rss?token=#{ users(:admin_user).word }"
end
def test_all_actions_txt
assert_success "/feed/text/admin/#{ users(:admin_user).word }"
assert_success "/todos.txt?token=#{ users(:admin_user).word }"
end
def test_all_actions_ical
assert_success "/feed/ical/admin/#{ users(:admin_user).word }"
assert_success "/todos.ics?token=#{ users(:admin_user).word }"
end
def test_all_actions_in_context_rss
assert_success "/contexts/agenda/todos.rss?token=#{ users(:admin_user).word }"
end
def test_all_actions_in_context_txt
assert_success "/contexts/agenda/todos.txt?token=#{ users(:admin_user).word }"
end
def test_all_actions_in_context_ical
assert_success "/contexts/agenda/todos.ics?token=#{ users(:admin_user).word }"
end
def test_all_actions_in_project_rss
assert_success "/projects/Build_a_working_time_machine/todos.rss?token=#{ users(:admin_user).word }"
end
def test_all_actions_in_project_txt
assert_success "/projects/Build_a_working_time_machine/todos.txt?token=#{ users(:admin_user).word }"
end
def test_all_actions_in_project_ical
assert_success "/projects/Build_a_working_time_machine/todos.ics?token=#{ users(:admin_user).word }"
end
def test_all_actions_due_today_or_earlier_rss
assert_success "/feed/rss/admin/#{ users(:admin_user).word }?due=0"
assert_success "/todos.rss?token=#{ users(:admin_user).word }&due=0"
end
def test_all_actions_due_today_or_earlier_txt
assert_success "/feed/text/admin/#{ users(:admin_user).word }?due=0"
assert_success "/todos.txt?token=#{ users(:admin_user).word }&due=0"
end
def test_all_actions_due_today_or_earlier_ical
assert_success "/feed/ical/admin/#{ users(:admin_user).word }?due=0"
assert_success "/todos.ics?token=#{ users(:admin_user).word }&due=0"
end
def test_all_actions_due_in_7_days_or_earlier_rss
assert_success "/feed/rss/admin/#{ users(:admin_user).word }?due=6"
assert_success "/todos.rss?token=#{ users(:admin_user).word }&due=6"
end
def test_all_actions_due_in_7_days_or_earlier_txt
assert_success "/feed/text/admin/#{ users(:admin_user).word }?due=6"
assert_success "/todos.txt?token=#{ users(:admin_user).word }&due=6"
end
def test_all_actions_due_in_7_days_or_earlier_ical
assert_success "/feed/ical/admin/#{ users(:admin_user).word }?due=6"
assert_success "/todos.ics?token=#{ users(:admin_user).word }&due=6"
end
def test_all_actions_completed_in_last_7_days_rss
assert_success "/feed/rss/admin/#{ users(:admin_user).word }?done=7"
assert_success "/todos.rss?token=#{ users(:admin_user).word }&done=7"
end
def test_all_actions_completed_in_last_7_days_txt
assert_success "/feed/text/admin/#{ users(:admin_user).word }?done=7"
assert_success "/todos.txt?token=#{ users(:admin_user).word }&done=7"
end
def test_all_contexts_rss

View file

@ -35,9 +35,9 @@ class Test::Unit::TestCase
@xml_document ||= HTML::Document.new(@response.body, false, true)
end
def assert_xml_select(*args)
def assert_xml_select(*args, &block)
@html_document = xml_document
assert_select(*args)
assert_select(*args, &block)
end
def next_week

View file

@ -112,5 +112,24 @@ class ContextTest < Test::Unit::TestCase
def test_title_reader_returns_name
assert_equal @agenda.name, @agenda.title
end
def test_feed_options
opts = Context.feed_options(users(:admin_user))
assert_equal 'Tracks Contexts', opts[:title], 'Unexpected value for :title key of feed_options'
assert_equal 'Lists all the contexts for Admin Schmadmin', opts[:description], 'Unexpected value for :description key of feed_options'
end
def test_hidden_attr_reader
assert !@agenda.hidden?
@agenda.hide = true
assert @agenda.hidden?
end
def test_summary
undone_todo_count = '5 actions'
assert_equal "<p>#{undone_todo_count}. Context is Active.</p>", @agenda.summary(undone_todo_count)
@agenda.hide = true
assert_equal "<p>#{undone_todo_count}. Context is Hidden.</p>", @agenda.summary(undone_todo_count)
end
end

View file

@ -142,9 +142,55 @@ class ProjectTest < Test::Unit::TestCase
def test_to_param_returns_url_friendly_name
assert_equal 'Build_a_working_time_machine', @timemachine.to_param
end
def test_title_reader_returns_name
assert_equal @timemachine.name, @timemachine.title
def test_null_object
p = Project.null_object
assert !p.hidden?
assert p.nil?
assert_nil p.id
end
def test_feed_options
opts = Project.feed_options(users(:admin_user))
assert_equal 'Tracks Projects', opts[:title], 'Unexpected value for :title key of feed_options'
assert_equal 'Lists all the projects for Admin Schmadmin', opts[:description], 'Unexpected value for :description key of feed_options'
end
def test_transition_to_another_state
assert_equal :active, @timemachine.current_state
@timemachine.transition_to(:hidden)
assert_equal :hidden, @timemachine.current_state
@timemachine.transition_to(:completed)
assert_equal :completed, @timemachine.current_state
@timemachine.transition_to(:active)
assert_equal :active, @timemachine.current_state
end
def test_transition_to_same_state
assert_equal :active, @timemachine.current_state
@timemachine.transition_to(:active)
assert_equal :active, @timemachine.current_state
end
def test_deferred_todo_count
assert_equal 1, @timemachine.deferred_todo_count
assert_equal 0, @moremoney.deferred_todo_count
@moremoney.todos[0].show_from = next_week
assert_equal 1, @moremoney.deferred_todo_count
end
def test_done_todo_count
assert_equal 0, @timemachine.done_todo_count
assert_equal 0, @moremoney.done_todo_count
@moremoney.todos[0].complete!
assert_equal 1, @moremoney.done_todo_count
end
def test_not_done_todo_count
assert_equal 2, @timemachine.not_done_todo_count
assert_equal 3, @moremoney.not_done_todo_count
@moremoney.todos[0].complete!
assert_equal 2, @moremoney.not_done_todo_count
end
end

View file

@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/../test_helper'
require 'date'
class TodoTest < Test::Unit::TestCase
fixtures :todos, :users, :contexts
fixtures :todos, :users, :contexts, :preferences
def setup
@not_completed1 = Todo.find(1).reload
@ -19,8 +19,8 @@ class TodoTest < Test::Unit::TestCase
assert_equal "Call Bill Gates to find out how much he makes per day", @not_completed1.description
assert_nil @not_completed1.notes
assert @not_completed1.completed? == false
assert_equal 1.week.ago.utc.strftime("%Y-%m-%d %H:%M"), @not_completed1.created_at.strftime("%Y-%m-%d %H:%M")
assert_equal 2.week.from_now.utc.strftime("%Y-%m-%d"), @not_completed1.due.strftime("%Y-%m-%d")
assert_equal 1.week.ago.utc.to_date.to_time.strftime("%Y-%m-%d %H:%M"), @not_completed1.created_at.strftime("%Y-%m-%d %H:%M")
assert_equal 2.week.from_now.utc.to_date.to_time.strftime("%Y-%m-%d"), @not_completed1.due.strftime("%Y-%m-%d")
assert_nil @not_completed1.completed_at
assert_equal 1, @not_completed1.user_id
end
@ -56,6 +56,16 @@ class TodoTest < Test::Unit::TestCase
assert_equal 1, @not_completed2.errors.count
assert_equal "is too long (maximum is 60000 characters)", @not_completed2.errors.on(:notes)
end
def test_validate_show_from_must_be_a_date_in_the_future
t = @not_completed2
t[:show_from] = 1.week.ago.to_date # we have to set this via the indexer because show_from=() updates the state
# and actual show_from value appropriately based on the date
assert_equal 1.week.ago.to_date, t.show_from
assert !t.save
assert_equal 1, t.errors.count
assert_equal "must be a date in the future", t.errors.on(:show_from)
end
def test_defer_an_existing_todo
@not_completed2
@ -74,4 +84,58 @@ class TodoTest < Test::Unit::TestCase
assert item.save, "should have saved successfully" + item.errors.to_xml
assert_equal :deferred, item.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.current_state
t.toggle_completion!
assert_equal :completed, t.current_state
t.toggle_completion!
assert_equal :active, t.current_state
end
def test_activate_and_save
t = @not_completed1
t.show_from = 1.week.from_now.to_date
t.save!
assert t.deferred?
t.reload
t.activate_and_save!
assert t.active?
t.reload
assert t.active?
end
def test_project_returns_null_object_when_nil
t = @not_completed1
assert !t.project.is_a?(NullProject)
t.project = nil
assert t.project.is_a?(NullProject)
end
def test_initial_state_defaults_to_active
t = Todo.new
t.description = 'foo'
t.context_id = 1
t.save!
t.reload
assert_equal :active, t.current_state
end
def test_initial_state_is_deferred_when_show_from_in_future
t = Todo.new
t.description = 'foo'
t.context_id = 1
t.show_from = 1.week.from_now.to_date
t.save!
t.reload
assert_equal :deferred, t.current_state
end
end

View file

@ -1,11 +1,28 @@
require File.dirname(__FILE__) + '/../test_helper'
module Tracks
class Config
def self.auth_schemes
['database', 'ldap']
end
end
end
class SimpleLdapAuthenticator
cattr_accessor :fake_success
def self.valid?(login, pass)
fake_success
end
end
class UserTest < Test::Unit::TestCase
fixtures :users, :preferences, :projects, :todos
fixtures :users, :preferences, :projects, :contexts, :todos
def setup
assert_equal "test", ENV['RAILS_ENV']
assert_equal "change-me", Tracks::Config.salt
assert_equal ['database', 'ldap'], Tracks::Config.auth_schemes
@admin_user = User.find(1)
@other_user = User.find(2)
end
@ -28,15 +45,15 @@ class UserTest < Test::Unit::TestCase
assert_equal "jane", @other_user.login
assert_equal "#{Digest::SHA1.hexdigest("#{Tracks::Config.salt}--sesame--")}", @other_user.password
assert_not_nil @other_user.word
assert @other_user.is_admin == false || @other_user.is_admin == 0
assert @other_user.is_admin == false || @other_user.is_admin == 0
end
# ============================================
# Validations
# ============================================
# Test a password shorter than 5 characters
#
#
def test_validate_short_password
assert_equal "#{Digest::SHA1.hexdigest("#{Tracks::Config.salt}--sesame--")}", @other_user.password
@other_user.password = "four"
@ -46,25 +63,25 @@ class UserTest < Test::Unit::TestCase
end
# Test a password longer than 40 characters
#
#
def test_validate_long_password
assert_equal "#{Digest::SHA1.hexdigest("#{Tracks::Config.salt}--sesame--")}", @other_user.password
@other_user.password = generate_random_string(41)
assert !@other_user.save
assert_equal 1, @other_user.errors.count
assert_equal "is too long (maximum is 40 characters)", @other_user.errors.on(:password)
end
end
# Test that correct length password is valid
#
#
def test_validate_correct_length_password
assert_equal "#{Digest::SHA1.hexdigest("#{Tracks::Config.salt}--sesame--")}", @other_user.password
@other_user.password = generate_random_string(6)
assert @other_user.save
end
# Test a missing password
#
#
def test_validate_missing_password
assert_equal 2, @other_user.id
@other_user.password = ""
@ -72,9 +89,9 @@ class UserTest < Test::Unit::TestCase
assert_equal 2, @other_user.errors.count
assert_equal ["is too short (minimum is 5 characters)", "can't be blank"], @other_user.errors.on(:password)
end
# Test a login shorter than 3 characters
#
#
def test_validate_short_login
assert_equal "jane", @other_user.login
@other_user.login = "ba"
@ -82,27 +99,27 @@ class UserTest < Test::Unit::TestCase
assert_equal 1, @other_user.errors.count
assert_equal "is too short (minimum is 3 characters)", @other_user.errors.on(:login)
end
# Test a login longer than 80 characters
#
#
def test_validate_long_login
assert_equal "jane", @other_user.login
@other_user.login = generate_random_string(81)
assert !@other_user.save
assert_equal 1, @other_user.errors.count
assert_equal "is too long (maximum is 80 characters)", @other_user.errors.on(:login)
end
end
# Test that correct length login is valid
#
#
def test_validate_correct_length_login
assert_equal "jane", @other_user.login
@other_user.login = generate_random_string(6)
assert @other_user.save
end
# Test a missing login
#
#
def test_validate_missing_login
assert_equal 2, @other_user.id
@other_user.login = ""
@ -110,39 +127,39 @@ class UserTest < Test::Unit::TestCase
assert_equal 2, @other_user.errors.count
assert_equal ["is too short (minimum is 3 characters)", "can't be blank"], @other_user.errors.on(:login)
end
def test_display_name_with_first_and_last_name_set
@other_user.first_name = "Jane"
@other_user.last_name = "Doe"
assert_equal "Jane Doe", @other_user.display_name
end
def test_display_name_with_first_name_set
@other_user.first_name = "Jane"
@other_user.last_name = nil
assert_equal "Jane", @other_user.display_name
end
def test_display_name_with_last_name_set
@other_user.first_name = nil
@other_user.last_name = "Doe"
assert_equal "Doe", @other_user.display_name
end
def test_display_name_with_neither_first_nor_last_name_set
@other_user.first_name = nil
@other_user.last_name = nil
assert_equal @other_user.login, @other_user.display_name
end
def test_prefs_is_short_for_preference
assert_equal @admin_user.preference, @admin_user.prefs
end
def test_to_param_returns_login
assert_equal @admin_user.login, @admin_user.to_param
end
def test_change_password
assert_not_nil User.authenticate(@admin_user.login, "abracadabra")
@admin_user.change_password("foobar", "foobar")
@ -152,28 +169,117 @@ class UserTest < Test::Unit::TestCase
end
def test_projects_next_project
moremoney = projects(:moremoney)
next_project = @admin_user.projects.next_from(moremoney)
assert_equal projects(:gardenclean), next_project
moremoney = projects(:moremoney)
next_project = @admin_user.projects.next_from(moremoney)
assert_equal projects(:gardenclean), next_project
end
def test_projects_previous_project
moremoney = projects(:moremoney)
previous_project = @admin_user.projects.previous_from(moremoney)
assert_equal projects(:timemachine), previous_project
moremoney = projects(:moremoney)
previous_project = @admin_user.projects.previous_from(moremoney)
assert_equal projects(:timemachine), previous_project
end
def test_projects_next_project_nil
gardenclean = projects(:gardenclean)
next_project = @admin_user.projects.next_from(gardenclean)
assert_nil next_project
gardenclean = projects(:gardenclean)
next_project = @admin_user.projects.next_from(gardenclean)
assert_nil next_project
end
def test_projects_previous_project_nil
timemachine = projects(:timemachine)
previous_project = @admin_user.projects.previous_from(timemachine)
assert_nil previous_project
timemachine = projects(:timemachine)
previous_project = @admin_user.projects.previous_from(timemachine)
assert_nil previous_project
end
def test_no_users_yet
assert !User.no_users_yet?
User.delete_all
assert User.no_users_yet?
end
def test_crypt_word_updates_word
old_word = @admin_user.word
@admin_user.crypt_word
assert_not_equal old_word, @admin_user.word
end
def test_find_admin
assert_equal @admin_user, User.find_admin
end
def test_validates_auth_type
@other_user.auth_type = 'dnacheck'
assert !@other_user.save
assert_equal 1, @other_user.errors.count
assert_equal "not a valid authentication type", @other_user.errors.on(:auth_type)
end
def test_authenticate_can_use_ldap
u = @other_user
u.auth_type = 'ldap'
u.save!
SimpleLdapAuthenticator.fake_success = false
assert_nil User.authenticate(u.login, 'foobar')
SimpleLdapAuthenticator.fake_success = true
assert_equal @other_user, User.authenticate(u.login, 'foobar')
end
def test_find_context_by_params
u = @admin_user
c = u.contexts.find_by_params('url_friendly_name' => 'agenda')
assert_equal contexts(:agenda), c
c = u.contexts.find_by_params('id' => 'agenda')
assert_equal contexts(:agenda), c
c = u.contexts.find_by_params('id' => '1')
assert_equal contexts(:agenda), c
c = u.contexts.find_by_params('context' => 'agenda')
assert_equal contexts(:agenda), c
c = u.contexts.find_by_params('context_id' => 'agenda')
assert_equal contexts(:agenda), c
end
def test_find_project_by_params
u = @admin_user
p = u.projects.find_by_params('url_friendly_name' => 'Build_a_working_time_machine')
assert_equal projects(:timemachine), p
p = u.projects.find_by_params('id' => 'Build_a_working_time_machine')
assert_equal projects(:timemachine), p
p = u.projects.find_by_params('id' => '1')
assert_equal projects(:timemachine), p
p = u.projects.find_by_params('project' => 'Build_a_working_time_machine')
assert_equal projects(:timemachine), p
p = u.projects.find_by_params('project_id' => 'Build_a_working_time_machine')
assert_equal projects(:timemachine), p
end
def test_update_project_positions
assert_equal 1, Project.find(1).position
assert_equal 2, Project.find(2).position
assert_equal 3, Project.find(3).position
@admin_user.projects.update_positions([2,1,3])
assert_equal 2, Project.find(1).position
assert_equal 1, Project.find(2).position
assert_equal 3, Project.find(3).position
end
def test_find_and_activate_deferred_todos_that_are_ready
assert_equal 1, @admin_user.deferred_todos.count
@admin_user.deferred_todos.find_and_activate_ready
@admin_user.deferred_todos.reload
assert_equal 0, @admin_user.deferred_todos.count
end
def test_completed_todos_completed_within
todos = @admin_user.completed_todos.completed_within(@admin_user.time - 1.day)
assert_equal 3, todos.length
end
def test_completed_todos_complete_more_than
todos = @admin_user.completed_todos.completed_more_than(@admin_user.time - 1.day)
assert_equal 1, todos.length
end
end