search_test.rb 6.81 KB
Newer Older
1
# frozen_string_literal: true
2

3
# Redmine - project management software
jplang's avatar
jplang committed
4
# Copyright (C) 2006-2017  Jean-Philippe Lang
5 6 7 8 9
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
10
#
11 12 13 14
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
15
#
16 17 18 19
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

20
require File.expand_path('../../test_helper', __FILE__)
21

22
class SearchTest < ActiveSupport::TestCase
23
  fixtures :users,
24
           :members,
25
           :member_roles,
26
           :projects,
27
           :projects_trackers,
28 29 30 31
           :roles,
           :enabled_modules,
           :issues,
           :trackers,
32 33
           :issue_statuses,
           :enumerations,
34 35 36 37 38 39
           :journals,
           :journal_details,
           :repositories,
           :changesets

  def setup
40
    User.current = nil
41
    @project = Project.find(1)
42
    @issue_keyword = '%unable to print recipes%'
43 44 45 46
    @issue = Issue.find(1)
    @changeset_keyword = '%very first commit%'
    @changeset = Changeset.find(100)
  end
47

48 49
  def test_search_by_anonymous
    User.current = nil
50

51
    r = Issue.search_results(@issue_keyword)
52
    assert r.include?(@issue)
53
    r = Changeset.search_results(@changeset_keyword)
54
    assert r.include?(@changeset)
55

56 57
    # Removes the :view_changesets permission from Anonymous role
    remove_permission Role.anonymous, :view_changesets
jplang's avatar
jplang committed
58
    User.current = nil
59

60
    r = Issue.search_results(@issue_keyword)
61
    assert r.include?(@issue)
62
    r = Changeset.search_results(@changeset_keyword)
63
    assert !r.include?(@changeset)
64

65 66
    # Make the project private
    @project.update_attribute :is_public, false
67
    r = Issue.search_results(@issue_keyword)
68
    assert !r.include?(@issue)
69
    r = Changeset.search_results(@changeset_keyword)
70 71
    assert !r.include?(@changeset)
  end
72

73 74 75
  def test_search_by_user
    User.current = User.find_by_login('rhill')
    assert User.current.memberships.empty?
76

77
    r = Issue.search_results(@issue_keyword)
78
    assert r.include?(@issue)
79
    r = Changeset.search_results(@changeset_keyword)
80
    assert r.include?(@changeset)
81

82 83
    # Removes the :view_changesets permission from Non member role
    remove_permission Role.non_member, :view_changesets
jplang's avatar
jplang committed
84
    User.current = User.find_by_login('rhill')
85

86
    r = Issue.search_results(@issue_keyword)
87
    assert r.include?(@issue)
88
    r = Changeset.search_results(@changeset_keyword)
89
    assert !r.include?(@changeset)
90

91 92
    # Make the project private
    @project.update_attribute :is_public, false
93
    r = Issue.search_results(@issue_keyword)
94
    assert !r.include?(@issue)
95
    r = Changeset.search_results(@changeset_keyword)
96 97
    assert !r.include?(@changeset)
  end
98

99 100 101
  def test_search_by_allowed_member
    User.current = User.find_by_login('jsmith')
    assert User.current.projects.include?(@project)
102

103
    r = Issue.search_results(@issue_keyword)
104
    assert r.include?(@issue)
105
    r = Changeset.search_results(@changeset_keyword)
106 107 108 109
    assert r.include?(@changeset)

    # Make the project private
    @project.update_attribute :is_public, false
110
    r = Issue.search_results(@issue_keyword)
111
    assert r.include?(@issue)
112
    r = Changeset.search_results(@changeset_keyword)
113 114 115 116 117 118 119
    assert r.include?(@changeset)
  end

  def test_search_by_unallowed_member
    # Removes the :view_changesets permission from user's and non member role
    remove_permission Role.find(1), :view_changesets
    remove_permission Role.non_member, :view_changesets
120

121 122
    User.current = User.find_by_login('jsmith')
    assert User.current.projects.include?(@project)
123

124
    r = Issue.search_results(@issue_keyword)
125
    assert r.include?(@issue)
126
    r = Changeset.search_results(@changeset_keyword)
127 128 129 130
    assert !r.include?(@changeset)

    # Make the project private
    @project.update_attribute :is_public, false
131
    r = Issue.search_results(@issue_keyword)
132
    assert r.include?(@issue)
133
    r = Changeset.search_results(@changeset_keyword)
134 135
    assert !r.include?(@changeset)
  end
136

137
  def test_search_issue_with_multiple_hits_in_journals
138 139
    issue = Issue.find(1)
    assert_equal 2, issue.journals.where("notes LIKE '%notes%'").count
140

141
    r = Issue.search_results('%notes%')
142
    assert_equal 1, r.size
143
    assert_equal issue, r.first
144
  end
145

146 147 148 149 150 151 152
  def test_search_should_be_case_insensitive
    issue = Issue.generate!(:subject => "AzerTY")

    r = Issue.search_results('AZERty')
    assert_include issue, r
  end

153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
  def test_search_should_be_case_insensitive_with_accented_characters
    unless sqlite?
      issue1 = Issue.generate!(:subject => "Special chars: ÖÖ")
      issue2 = Issue.generate!(:subject => "Special chars: Öö")
      r = Issue.search_results('ÖÖ')
      assert_include issue1, r
      assert_include issue2, r
    end
  end

  def test_search_should_be_case_and_accent_insensitive_with_mysql
    if mysql?
      issue1 = Issue.generate!(:subject => "OO")
      issue2 = Issue.generate!(:subject => "oo")
      r = Issue.search_results('ÖÖ')
      assert_include issue1, r
      assert_include issue2, r
    end
171 172
  end

173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
  def test_search_should_be_case_and_accent_insensitive_with_postgresql_and_noaccent_extension
    if postgresql?
      skip unless Redmine::Database.postgresql_version >= 90000
      # Extension will be rollbacked with the test transaction
      ActiveRecord::Base.connection.execute("CREATE EXTENSION IF NOT EXISTS unaccent")
      Redmine::Database.reset
      assert Redmine::Database.postgresql_unaccent?
      issue1 = Issue.generate!(:subject => "OO")
      issue2 = Issue.generate!(:subject => "oo")
      r = Issue.search_results('ÖÖ')
      assert_include issue1, r
      assert_include issue2, r
    end
  ensure
    Redmine::Database.reset
  end

190 191 192 193 194 195 196 197
  def test_fetcher_should_handle_accents_in_phrases
    f = Redmine::Search::Fetcher.new('No special chars "in a phrase"', User.anonymous, %w(issues), Project.all)
    assert_equal ['No', 'special', 'chars', 'in a phrase'], f.tokens

    f = Redmine::Search::Fetcher.new('Special chars "in a phrase Öö"', User.anonymous, %w(issues), Project.all)
    assert_equal ['Special', 'chars', 'in a phrase Öö'], f.tokens
  end

198 199 200 201 202
  def test_fetcher_should_exclude_single_character_tokens_except_for_chinese_characters
    f = Redmine::Search::Fetcher.new('ca f é 漢 あ 한', User.anonymous, %w(issues), Project.all)
    assert_equal ['ca', '漢'], f.tokens
  end

203
  private
204

205 206 207 208 209
  def remove_permission(role, permission)
    role.permissions = role.permissions - [ permission ]
    role.save
  end
end