mirror of
https://github.com/TracksApp/tracks.git
synced 2026-01-31 13:15:17 +01:00
fix #827. You can now select todos with tags using OR and AND
/todos/tag/tagA,tagB?and=tagC will select all todos with (tagA or tagB) AND tagC
This commit is contained in:
parent
2accbd0a32
commit
58d8bc56d1
9 changed files with 255 additions and 152 deletions
|
|
@ -644,4 +644,68 @@ class TodosControllerTest < ActionController::TestCase
|
|||
assert_select("div#notes_todo_#{todo.id} a", 'link me to onenote')
|
||||
assert_select("div#notes_todo_#{todo.id} a[href=onenote:///E:\\OneNote\\dir\\notes.one#PAGE&section-id={FD597D3A-3793-495F-8345-23D34A00DD3B}&page-id={1C95A1C7-6408-4804-B3B5-96C28426022B}&end]", 'link me to onenote')
|
||||
end
|
||||
|
||||
def test_get_boolean_expression_from_parameters_of_tag_view_single_tag
|
||||
login_as(:admin_user)
|
||||
get :tag, :name => "single"
|
||||
assert_equal true, assigns['single_tag'], "should recognize it is a single tag name"
|
||||
assert_equal "single", assigns['tag_expr'][0][0], "should store the single tag"
|
||||
end
|
||||
|
||||
def test_get_boolean_expression_from_parameters_of_tag_view_multiple_tags
|
||||
login_as(:admin_user)
|
||||
get :tag, :name => "multiple", :and => "tags", :and1 => "present", :and2 => "here"
|
||||
assert_equal false, assigns['single_tag'], "should recognize it has multiple tags"
|
||||
assert_equal 4, assigns['tag_expr'].size, "should have 4 AND expressions"
|
||||
end
|
||||
|
||||
def test_get_boolean_expression_from_parameters_of_tag_view_multiple_tags_without_digitless_and
|
||||
login_as(:admin_user)
|
||||
get :tag, :name => "multiple", :and1 => "tags", :and2 => "present", :and3 => "here"
|
||||
assert_equal false, assigns['single_tag'], "should recognize it has multiple tags"
|
||||
assert_equal 4, assigns['tag_expr'].size, "should have 4 AND expressions"
|
||||
end
|
||||
|
||||
def test_get_boolean_expression_from_parameters_of_tag_view_multiple_ORs
|
||||
login_as(:admin_user)
|
||||
get :tag, :name => "multiple,tags,present"
|
||||
assert_equal false, assigns['single_tag'], "should recognize it has multiple tags"
|
||||
assert_equal 1, assigns['tag_expr'].size, "should have 1 expressions"
|
||||
assert_equal 3, assigns['tag_expr'][0].size, "should have 3 ORs in 1st expression"
|
||||
end
|
||||
|
||||
def test_get_boolean_expression_from_parameters_of_tag_view_multiple_ORs_and_ANDS
|
||||
login_as(:admin_user)
|
||||
get :tag, :name => "multiple,tags,present", :and => "here,is,two", :and1=>"and,three"
|
||||
assert_equal false, assigns['single_tag'], "should recognize it has multiple tags"
|
||||
assert_equal 3, assigns['tag_expr'].size, "should have 3 expressions"
|
||||
assert_equal 3, assigns['tag_expr'][0].size, "should have 3 ORs in 1st expression"
|
||||
assert_equal 3, assigns['tag_expr'][1].size, "should have 3 ORs in 2nd expression"
|
||||
assert_equal 2, assigns['tag_expr'][2].size, "should have 2 ORs in 3rd expression"
|
||||
end
|
||||
|
||||
def test_set_right_title
|
||||
login_as(:admin_user)
|
||||
|
||||
get :tag, :name => "foo"
|
||||
assert_equal "foo", assigns['tag_title']
|
||||
get :tag, :name => "foo,bar", :and => "baz"
|
||||
assert_equal "foo,bar AND baz", assigns['tag_title']
|
||||
end
|
||||
|
||||
def test_set_default_tag
|
||||
login_as(:admin_user)
|
||||
|
||||
get :tag, :name => "foo"
|
||||
assert_equal "foo", assigns['initial_tags']
|
||||
get :tag, :name => "foo,bar", :and => "baz"
|
||||
assert_equal "foo", assigns['initial_tags']
|
||||
end
|
||||
|
||||
def test_tag_text_feed_not_accessible_to_anonymous_user_without_token
|
||||
login_as nil
|
||||
get :tag, {:name => "foo", :format => "txt" }
|
||||
assert_response 401
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,62 +0,0 @@
|
|||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
require 'todos_controller'
|
||||
|
||||
# Re-raise errors caught by the controller.
|
||||
class TodosController; def rescue_action(e) raise e end; end
|
||||
|
||||
class TodosControllerTest < ActionController::TestCase
|
||||
fixtures :users, :preferences, :projects, :contexts, :todos, :tags, :taggings, :recurring_todos
|
||||
|
||||
def test_get_boolean_expression_from_parameters_of_tag_view_single_tag
|
||||
login_as(:admin_user)
|
||||
get :tag, :name => "single"
|
||||
assert_equal true, assigns['single_tag'], "should recognize it is a single tag name"
|
||||
assert_equal "single", assigns['tag_expr'][0][0], "should store the single tag"
|
||||
end
|
||||
|
||||
def test_get_boolean_expression_from_parameters_of_tag_view_multiple_tags
|
||||
login_as(:admin_user)
|
||||
get :tag, :name => "multiple", :and => "tags", :and1 => "present", :and2 => "here"
|
||||
assert_equal false, assigns['single_tag'], "should recognize it has multiple tags"
|
||||
assert_equal 4, assigns['tag_expr'].size, "should have 4 AND expressions"
|
||||
end
|
||||
|
||||
def test_get_boolean_expression_from_parameters_of_tag_view_multiple_tags_without_digitless_and
|
||||
login_as(:admin_user)
|
||||
get :tag, :name => "multiple", :and1 => "tags", :and2 => "present", :and3 => "here"
|
||||
assert_equal false, assigns['single_tag'], "should recognize it has multiple tags"
|
||||
assert_equal 4, assigns['tag_expr'].size, "should have 4 AND expressions"
|
||||
end
|
||||
|
||||
def test_get_boolean_expression_from_parameters_of_tag_view_multiple_ORs
|
||||
login_as(:admin_user)
|
||||
get :tag, :name => "multiple,tags,present"
|
||||
assert_equal false, assigns['single_tag'], "should recognize it has multiple tags"
|
||||
assert_equal 1, assigns['tag_expr'].size, "should have 1 expressions"
|
||||
assert_equal 3, assigns['tag_expr'][0].size, "should have 3 ORs in 1st expression"
|
||||
end
|
||||
|
||||
def test_get_boolean_expression_from_parameters_of_tag_view_multiple_ORs_and_ANDS
|
||||
login_as(:admin_user)
|
||||
get :tag, :name => "multiple,tags,present", :and => "here,is,two", :and1=>"and,three"
|
||||
assert_equal false, assigns['single_tag'], "should recognize it has multiple tags"
|
||||
assert_equal 3, assigns['tag_expr'].size, "should have 3 expressions"
|
||||
assert_equal 3, assigns['tag_expr'][0].size, "should have 3 ORs in 1st expression"
|
||||
assert_equal 3, assigns['tag_expr'][1].size, "should have 3 ORs in 2nd expression"
|
||||
assert_equal 2, assigns['tag_expr'][2].size, "should have 2 ORs in 3rd expression"
|
||||
end
|
||||
|
||||
def test_get_ids_from_tag_expr
|
||||
login_as(:admin_user)
|
||||
|
||||
# make sure the tags exits
|
||||
# "multiple,tags,present,here,is,two,and,three".split(',').each { |tag| Tag.find_or_create_by_name(:name=>tag)}
|
||||
|
||||
get :tag, :name => "foo,bar", :and => "baz"
|
||||
|
||||
assert_equal 1, assigns['tag_ids'][0][0], "first id should be 1 for foo"
|
||||
assert_equal 2, assigns['tag_ids'][0][1], "second id should be 2 for bar"
|
||||
assert_equal 3, assigns['tag_ids'][1][0], "third id should be 3 for baz"
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -9,7 +9,7 @@ class TodoTest < ActiveSupport::TestCase
|
|||
@not_completed2 = Todo.find(2).reload
|
||||
@completed = Todo.find(8).reload
|
||||
end
|
||||
|
||||
|
||||
# Test loading a todo item
|
||||
def test_load
|
||||
assert_kind_of Todo, @not_completed1
|
||||
|
|
@ -24,13 +24,13 @@ class TodoTest < ActiveSupport::TestCase
|
|||
assert_nil @not_completed1.completed_at
|
||||
assert_equal 1, @not_completed1.user_id
|
||||
end
|
||||
|
||||
|
||||
def test_completed
|
||||
assert_kind_of Todo, @completed
|
||||
assert @completed.completed?
|
||||
assert_not_nil @completed.completed_at
|
||||
end
|
||||
|
||||
|
||||
def test_completed_at_cleared_after_toggle_to_active
|
||||
assert_kind_of Todo, @completed
|
||||
assert @completed.completed?
|
||||
|
|
@ -38,8 +38,8 @@ class TodoTest < ActiveSupport::TestCase
|
|||
assert @completed.active?
|
||||
assert_nil @completed.completed_at
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
# Validation tests
|
||||
#
|
||||
def test_validate_presence_of_description
|
||||
|
|
@ -49,7 +49,7 @@ class TodoTest < ActiveSupport::TestCase
|
|||
assert_equal 1, @not_completed2.errors.count
|
||||
assert_equal "can't be blank", @not_completed2.errors.on(:description)
|
||||
end
|
||||
|
||||
|
||||
def test_validate_length_of_description
|
||||
assert_equal "Call dinosaur exterminator", @not_completed2.description
|
||||
@not_completed2.description = generate_random_string(101)
|
||||
|
|
@ -57,7 +57,7 @@ class TodoTest < ActiveSupport::TestCase
|
|||
assert_equal 1, @not_completed2.errors.count
|
||||
assert_equal "is too long (maximum is 100 characters)", @not_completed2.errors.on(:description)
|
||||
end
|
||||
|
||||
|
||||
def test_validate_length_of_notes
|
||||
assert_equal "Ask him if I need to hire a skip for the corpses.", @not_completed2.notes
|
||||
@not_completed2.notes = generate_random_string(60001)
|
||||
|
|
@ -74,7 +74,7 @@ class TodoTest < ActiveSupport::TestCase
|
|||
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
|
||||
assert_equal :active, @not_completed2.aasm_current_state
|
||||
|
|
@ -82,20 +82,20 @@ class TodoTest < ActiveSupport::TestCase
|
|||
assert @not_completed2.save, "should have saved successfully" + @not_completed2.errors.to_xml
|
||||
assert_equal :deferred, @not_completed2.aasm_current_state
|
||||
end
|
||||
|
||||
|
||||
def test_create_a_new_deferred_todo
|
||||
user = users(:other_user)
|
||||
todo = user.todos.build
|
||||
todo.show_from = next_week
|
||||
todo.context_id = 1
|
||||
todo.description = 'foo'
|
||||
todo.description = 'foo'
|
||||
assert todo.save, "should have saved successfully" + todo.errors.to_xml
|
||||
assert_equal :deferred, todo.aasm_current_state
|
||||
end
|
||||
|
||||
def test_create_a_new_deferred_todo_by_passing_attributes
|
||||
user = users(:other_user)
|
||||
todo = user.todos.build(:show_from => next_week, :context_id => 1, :description => 'foo')
|
||||
todo = user.todos.build(:show_from => next_week, :context_id => 1, :description => 'foo')
|
||||
assert todo.save, "should have saved successfully" + todo.errors.to_xml
|
||||
assert_equal :deferred, todo.aasm_current_state
|
||||
end
|
||||
|
|
@ -167,15 +167,15 @@ class TodoTest < ActiveSupport::TestCase
|
|||
t.reload
|
||||
assert_equal :deferred, t.aasm_current_state
|
||||
end
|
||||
|
||||
|
||||
def test_todo_is_not_starred
|
||||
assert !@not_completed1.starred?
|
||||
end
|
||||
|
||||
|
||||
def test_todo_2_is_not_starred
|
||||
assert !Todo.find(2).starred?
|
||||
end
|
||||
|
||||
|
||||
def test_todo_is_starred_after_starred_tag_is_added
|
||||
@not_completed1._add_tags('starred')
|
||||
assert @not_completed1.starred?
|
||||
|
|
@ -185,7 +185,7 @@ class TodoTest < ActiveSupport::TestCase
|
|||
@not_completed1.toggle_star!
|
||||
assert @not_completed1.starred?
|
||||
end
|
||||
|
||||
|
||||
def test_todo_is_not_starred_after_toggle_starred_twice
|
||||
@not_completed1.toggle_star!
|
||||
@not_completed1.toggle_star!
|
||||
|
|
@ -239,4 +239,101 @@ class TodoTest < ActiveSupport::TestCase
|
|||
assert_equal 2, @predecessor_array.size
|
||||
end
|
||||
|
||||
def test_finding_todos_with_a_tag
|
||||
todo = @not_completed1
|
||||
todo.tag_list = "a, b, c"
|
||||
todo.save!
|
||||
|
||||
tag_a = Tag.find_by_name("a")
|
||||
tag_b = Tag.find_by_name("b")
|
||||
tag_c = Tag.find_by_name("c")
|
||||
|
||||
todos_with_a = Todo.with_tag(tag_a)
|
||||
assert 1, todos_with_a.count
|
||||
assert_equal todo.description, todos_with_a.first.description
|
||||
|
||||
todos_with_b = Todo.with_tag(tag_b)
|
||||
assert 1, todos_with_b.count
|
||||
assert_equal todo.id, todos_with_b.first.id
|
||||
|
||||
todo2 = @not_completed2
|
||||
todo2.tag_list = "a, c, d"
|
||||
todo2.save!
|
||||
|
||||
tag_d = Tag.find_by_name("d")
|
||||
|
||||
todos_with_a = Todo.with_tag(tag_a)
|
||||
assert 2, todos_with_a.count
|
||||
|
||||
todos_with_d = Todo.with_tag(tag_d)
|
||||
assert 1, todos_with_a.count
|
||||
end
|
||||
|
||||
def test_finding_todos_with_more_tags_using_OR
|
||||
todo1 = @not_completed1
|
||||
todo1.tag_list = "a, b, c"
|
||||
todo1.save!
|
||||
|
||||
todo2 = @not_completed2
|
||||
todo2.tag_list = "a, c, d"
|
||||
todo2.save!
|
||||
|
||||
tag_a = Tag.find_by_name("a")
|
||||
tag_b = Tag.find_by_name("b")
|
||||
tag_c = Tag.find_by_name("c")
|
||||
tag_d = Tag.find_by_name("d")
|
||||
|
||||
# overlapping tags
|
||||
tag_ids = [tag_a.id, tag_c.id]
|
||||
todos_with_a_or_c = Todo.with_tags(tag_ids)
|
||||
assert 2, todos_with_a_or_c.count
|
||||
|
||||
# non-overlapping tags
|
||||
tag_ids = [tag_b.id, tag_d.id]
|
||||
todos_with_b_or_d = Todo.with_tags(tag_ids)
|
||||
assert 2, todos_with_b_or_d.count
|
||||
end
|
||||
|
||||
def test_finding_todos_with_more_tags_using_AND
|
||||
todo1 = @not_completed1
|
||||
todo1.tag_list = "a, b, c"
|
||||
todo1.save!
|
||||
|
||||
todo2 = @not_completed2
|
||||
todo2.tag_list = "a, c, d"
|
||||
todo2.save!
|
||||
|
||||
tag_a_id = Tag.find_by_name("a").id
|
||||
tag_b_id = Tag.find_by_name("b").id
|
||||
|
||||
todos_with_a_and_b = Todo.with_tags([tag_a_id]).with_tags([tag_b_id])
|
||||
assert 1, todos_with_a_and_b.count
|
||||
assert todo1.id, todos_with_a_and_b.first.id
|
||||
end
|
||||
|
||||
def test_finding_todos_with_more_tags_using_AND_and_OR
|
||||
todo1 = @not_completed1
|
||||
todo1.tag_list = "a, b, c"
|
||||
todo1.save!
|
||||
|
||||
todo2 = @not_completed2
|
||||
todo2.tag_list = "a, c, d"
|
||||
todo2.save!
|
||||
|
||||
tag_a_id = Tag.find_by_name("a").id
|
||||
tag_b_id = Tag.find_by_name("b").id
|
||||
tag_c_id = Tag.find_by_name("c").id
|
||||
|
||||
todos_with_aORc_and_b = Todo.with_tags([tag_a_id, tag_c_id]).with_tags([tag_b_id])
|
||||
assert 1, todos_with_aORc_and_b.count
|
||||
assert todo1.id, todos_with_aORc_and_b.first.id
|
||||
|
||||
# let todo2 fit the expression
|
||||
todo2.tag_list = "a, b, r"
|
||||
todo2.save!
|
||||
todos_with_aORc_and_b = Todo.with_tags([tag_a_id, tag_c_id]).with_tags([tag_b_id])
|
||||
assert 2, todos_with_aORc_and_b.count
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue