bento_search 1.7.0.beta.1 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,17 @@
1
+ <% # An initially hidden div with loading msg/spinner that will be shown
2
+ # by js on ajax load
3
+ %>
4
+
5
+ <noscript>
6
+ <%= I18n.t("bento_search.ajax_noscript") %>
7
+ </noscript>
8
+
9
+ <%=
10
+ content_tag(:div,
11
+ :class => "bento_search_ajax_loading",
12
+ :style => "display:none") do
13
+ image_tag("bento_search/large_loader.gif",
14
+ :alt => I18n.translate("bento_search.ajax_loading")
15
+ )
16
+ end
17
+ %>
@@ -1,6 +1,6 @@
1
- <%= link_to(link.label, link.url,
2
- :rel => link.rel,
1
+ <%= link_to(link.label, link.url,
2
+ :rel => link.rel,
3
3
  :class => (link.style_classes + ["bento_search_link", "btn", "btn-mini", "btn-default", "btn-sm"]),
4
- :target => link.target
4
+ :target => local_assigns[:target] || link.target
5
5
  ) %>
6
6
 
@@ -47,6 +47,18 @@ module BentoSearch
47
47
  # Avoid deprecation warnings in ruby 2.3.0
48
48
  RubyTimeoutClass = (defined?(Timeout::Error) ? Timeout::Error : TimeoutError)
49
49
 
50
+ @@defaults = Confstruct::Configuration.new(
51
+ error_partial: 'bento_search/search_error',
52
+ item_partial: 'bento_search/std_item',
53
+ no_results_partial: 'bento_search/no_results',
54
+ ajax_loading_partial: 'bento_search/ajax_loading'
55
+ )
56
+ def self.set_defaults(hash)
57
+ @@defaults.merge!(hash)
58
+ end
59
+ def self.defaults
60
+ @@defaults
61
+ end
50
62
  end
51
63
 
52
64
 
@@ -1,5 +1,7 @@
1
1
  module BentoSearch
2
2
  class Engine < ::Rails::Engine
3
3
  #isolate_namespace BentoSearch
4
+
5
+ config.assets.precompile += %w( bento_search/large_loader.gif )
4
6
  end
5
7
  end
@@ -1,3 +1,3 @@
1
1
  module BentoSearch
2
- VERSION = "1.7.0.beta.1"
2
+ VERSION = "1.7.0"
3
3
  end
@@ -2,12 +2,14 @@ require 'test_helper'
2
2
 
3
3
  class EdsEngineTest < ActiveSupport::TestCase
4
4
  extend TestWithCassette
5
-
5
+
6
6
  @@user_id = (ENV['EDS_USER_ID'] || 'DUMMY_USER_ID')
7
7
  @@password = (ENV['EDS_PASSWORD'] || 'DUMMY_PWD')
8
- @@profile = (ENV['EDS_PROFILE'] || 'edsapi')
9
-
10
-
8
+ @@profile = (ENV['EDS_PROFILE'] || 'wsapi')
9
+ # something where the first hit will be from catalog for the profile above
10
+ @@catalog_result_query = (ENV['EDS_CATALOG_RESULT_QUERY'] || 'New York exposed the gilded age police scandal that launched the progressive era Daniel Czitrom')
11
+ @@catalog_ebook_result_query = (ENV['EDS_CATALOG_EBOOK_RESULT_QUERY'] || 'Stakeholder forum on federal wetlands mitigation environmental law institute')
12
+ @@catalog_custom_result_query = (ENV['EDS_CATALOG_CUSTOM_RESULT_QUERY'] || 'Drafting New York Civil-Litigation Documents Part XXIV Summary-Judgment Motions Continued')
11
13
  VCR.configure do |c|
12
14
  c.filter_sensitive_data("DUMMY_USER_ID", :eds) { @@user_id }
13
15
  c.filter_sensitive_data("DUMMY_PWD", :eds) { @@password }
@@ -16,140 +18,170 @@ class EdsEngineTest < ActiveSupport::TestCase
16
18
  def setup
17
19
  # Class-level remembered auth token messes up our VCR-recording,
18
20
  # since one test will try to use an auth token fetched by a different
19
- # test. For testing, blank out the cache before each test.
21
+ # test. For testing, blank out the cache before each test.
20
22
  BentoSearch::EdsEngine.remembered_auth = nil
21
23
 
22
24
  @config = {:user_id => @@user_id, :password => @@password, :profile => @@profile, :auth => true}
23
25
  @engine = BentoSearch::EdsEngine.new(@config)
24
26
  end
25
-
27
+
26
28
  test "construct simple search, with comma escaping" do
27
29
  url = @engine.construct_search_url(:query => "foo, bar,baz")
28
-
30
+
29
31
  query_params = CGI.parse( URI.parse(url).query )
30
32
 
31
33
  assert_equal ["all"], query_params["searchmode"]
32
-
34
+
33
35
  assert_equal ["detailed"], query_params["view"]
34
-
35
- assert_equal ["AND,foo bar baz"], query_params["query"]
36
+
37
+ assert_equal ["AND,foo bar baz"], query_params["query"]
36
38
  end
37
-
39
+
38
40
  test "only_source_types config" do
39
41
  engine = BentoSearch::EdsEngine.new( @config.merge(:only_source_types => [
40
42
  "Academic Journals", "Magazines"
41
43
  ]))
42
-
44
+
43
45
  url = engine.construct_search_url(:query => "cancer", :per_page => 10)
44
-
46
+
45
47
  query_params = CGI.parse( URI.parse(url).query )
46
-
48
+
47
49
  # should be
48
50
  # facetfilter=1,SourceType:Academic Journals,SourceType:Magazines
49
51
  # but with value query encoded
50
-
52
+
51
53
  assert_equal 1, query_params["facetfilter"].length
52
-
54
+
53
55
  facetfilter = query_params["facetfilter"].first
54
-
56
+
55
57
  parts = facetfilter.split(",")
56
-
58
+
57
59
  assert_equal 3, parts.length
58
-
60
+
59
61
  assert_equal "1", parts.first
60
-
62
+
61
63
  assert_includes parts, "SourceType:Academic Journals"
62
- assert_includes parts, "SourceType:Magazines"
64
+ assert_includes parts, "SourceType:Magazines"
63
65
  end
64
-
66
+
65
67
  def test_has_http_timeout_set
66
68
  assert_equal BentoSearch::EdsEngine::HttpTimeout, @engine.http_client.receive_timeout
67
69
  assert_equal BentoSearch::EdsEngine::HttpTimeout, @engine.http_client.send_timeout
68
70
  assert_equal BentoSearch::EdsEngine::HttpTimeout, @engine.http_client.connect_timeout
69
- end
71
+ end
72
+
70
73
 
71
-
72
74
  test_with_cassette("get_auth_token failure", :eds) do
73
75
  engine = BentoSearch::EdsEngine.new(:user_id => "bad", :password => "bad", :profile => "bad")
74
76
  exception = assert_raise(BentoSearch::EdsEngine::EdsCommException) do
75
77
  token = engine.get_auth_token
76
- end
77
-
78
+ end
79
+
78
80
  assert_present exception.http_status
79
- assert_present exception.http_body
81
+ assert_present exception.http_body
80
82
  end
81
-
83
+
82
84
  test_with_cassette("get_auth_token", :eds) do
83
85
  token = @engine.get_auth_token
84
-
86
+
85
87
  assert_present token
86
88
  end
87
-
89
+
88
90
  # No idea why VCR is having buggy problems with record and playback of this request
89
- # We'll emcompass it in the get_with_auth test
91
+ # We'll emcompass it in the get_with_auth test
90
92
  #
91
- #test_with_cassette("with_session", :eds, :match_requests_on => [:method, :uri, :headers, :body]) do
93
+ #test_with_cassette("with_session", :eds, :match_requests_on => [:method, :uri, :headers, :body]) do
92
94
  # @engine.with_session do |session_token|
93
95
  # assert_present session_token
94
- # end
96
+ # end
95
97
  #end
96
-
98
+
97
99
  test_with_cassette("get_with_auth", :eds) do
98
100
  @engine.with_session do |session_token|
99
101
  assert_present session_token
100
-
102
+
101
103
  # Coudln't get 'info' request to work even as a test, let's
102
- # try a simple search.
104
+ # try a simple search.
103
105
  url = "#{@engine.configuration.base_url}info"
104
106
  response = @engine.get_with_auth(url, session_token)
105
-
107
+
106
108
  assert_present response
107
109
  assert_kind_of Nokogiri::XML::Document, response
108
-
109
- assert_nil response.at_xpath("//ErrorNumber"), "no error report in result"
110
- end
110
+
111
+ assert_nil response.at_xpath("//ErrorNumber"), "no error report in result"
112
+ end
111
113
  end
112
-
114
+
113
115
  test_with_cassette("get_with_auth recovers from bad auth", :eds) do
114
116
  @engine.with_session do |session_token|
115
117
  BentoSearch::EdsEngine.remembered_auth = "BAD"
116
-
118
+
117
119
  url = "#{@engine.configuration.base_url}info"
118
120
  response = @engine.get_with_auth(url, session_token)
119
-
121
+
120
122
  assert_present response
121
123
  assert_kind_of Nokogiri::XML::Document, response
122
-
123
- assert_nil response.at_xpath("//ErrorNumber"), "no error report in result"
124
- end
125
-
124
+
125
+ assert_nil response.at_xpath("//ErrorNumber"), "no error report in result"
126
+ end
127
+
126
128
  BentoSearch::EdsEngine.remembered_auth = nil
127
129
  end
128
-
130
+
129
131
  test_with_cassette("basic search smoke test", :eds) do
130
- results = @engine.search("cancer")
131
-
132
+ results = @engine.search("cancer")
133
+
132
134
  assert_present results
133
-
135
+
134
136
  assert_present results.total_items
135
-
137
+
136
138
  first = results.first
137
139
 
138
140
  assert_present first.title
139
141
  assert first.title.html_safe? # yeah, for now we use EDS html
140
-
142
+
141
143
  assert_present first.abstract
142
144
  assert_present first.abstract.html_safe?
143
-
144
- assert_present first.custom_data["citation_blob"]
145
-
145
+
146
+ assert_present first.custom_data["citation_blob"]
147
+
148
+ assert_present first.source_title
149
+ assert_present first.issn
150
+ assert_present first.volume
151
+ assert_present first.issue
152
+ assert_present first.year
153
+ assert_present first.publication_date
154
+ assert_present first.start_page
155
+ assert_present first.end_page
156
+
157
+ assert_present first.doi
158
+
146
159
  assert_present first.format_str
147
-
160
+
148
161
  assert_present first.unique_id
149
162
  # EDS id is db name, colon, accession number
150
163
  assert_match /.+\:.+/, first.unique_id
151
164
  end
152
-
153
-
165
+
166
+ test_with_cassette("catalog query", :eds) do
167
+ results = @engine.search(@@catalog_result_query)
168
+
169
+ cat_result = results.first
170
+
171
+ assert_present cat_result.custom_data[:holdings]
172
+ assert cat_result.custom_data[:holdings].all? { |h| h.location.present? && h.call_number.present? }
173
+ end
174
+
175
+ test_with_cassette("catalog ebook query", :eds) do
176
+ result = @engine.search(@@catalog_ebook_result_query).first
177
+
178
+ assert_present result.other_links
179
+ end
180
+
181
+ test_with_cassette("FullText CustomLink", :eds) do
182
+ result = @engine.search(@@catalog_custom_result_query).first
183
+ assert_present result
184
+ assert result.other_links.any? { |r| r.label.present? && r.label != "Link" && r.url.present? && URI::regexp =~ r.url && r.rel == "alternate"}
185
+ end
154
186
  end
155
187
 
@@ -288,5 +288,16 @@ class ParseSearchArgumentsTest < ActiveSupport::TestCase
288
288
  assert_equal "I am a horrible engine", results.error[:exception].message, "results.error has right exception"
289
289
  end
290
290
 
291
+ def test_cover_consistency_api
292
+ d = Dummy.new()
293
+ assert_nil d.engine_id
294
+ assert_equal({}, d.display_configuration)
295
+
296
+ d = Dummy.new(id: 'test', for_display: { testkey: 'test' })
297
+ assert_equal 'test', d.engine_id
298
+ assert_equal({ testkey: 'test' }, d.display_configuration)
299
+
300
+ end
301
+
291
302
  end
292
303
 
@@ -132,6 +132,7 @@ class SearchEngineTest < ActiveSupport::TestCase
132
132
 
133
133
  assert results.failed?, "marked failed"
134
134
  assert_present results.error
135
+ assert_present results.error[:exception]
135
136
  assert_equal "raises", results.engine_id
136
137
  assert_present results.search_args
137
138
  assert_equal "foo", results.search_args[:query]
@@ -139,6 +140,17 @@ class SearchEngineTest < ActiveSupport::TestCase
139
140
  assert_equal( {:foo => "foo"}, results.display_configuration )
140
141
  end
141
142
 
143
+ test "can set auto rescued exceptions on instance" do
144
+ engine = MockEngine.new(:id => "raises", :raise_exception_class => "StandardError", :for_display => {:foo => "foo"})
145
+ engine.auto_rescued_exceptions = [StandardError]
146
+
147
+ results = engine.search("foo", :per_page => 20)
148
+
149
+ assert results.failed?, "marked failed"
150
+ assert_present results.error
151
+ assert_present results.error[:exception]
152
+ end
153
+
142
154
 
143
155
  test "has empty :for_display config" do
144
156
  engine = MockEngine.new
@@ -0,0 +1,75 @@
1
+ require 'test_helper'
2
+
3
+ # Doesn't really test the concurrency, but basic smoke test with fake
4
+ # searchers.
5
+ class ConcurrentSearcherTest < ActiveSupport::TestCase
6
+ setup do
7
+ BentoSearch.register_engine("one") do |conf|
8
+ conf.engine = "MockEngine"
9
+ end
10
+ BentoSearch.register_engine("two") do |conf|
11
+ conf.engine = "MockEngine"
12
+ end
13
+ BentoSearch.register_engine("three") do |conf|
14
+ conf.engine = "MockEngine"
15
+ end
16
+
17
+ BentoSearch.register_engine("raiser") do |conf|
18
+ conf.engine = "MockEngine"
19
+ conf.raise_exception_class = "StandardError"
20
+ end
21
+ end
22
+
23
+ teardown do
24
+ BentoSearch.reset_engine_registrations!
25
+ end
26
+
27
+
28
+ def test_concurrent_search
29
+ searcher = BentoSearch::ConcurrentSearcher.new(:one, :two, :three)
30
+ returnval = searcher.search("cancer")
31
+
32
+ assert_same searcher, returnval
33
+
34
+ results = searcher.results
35
+
36
+ assert_kind_of Hash, results
37
+ assert_equal ["one", "two", "three"].sort, results.keys.sort
38
+
39
+ ["one", "two", "three"].each do |key|
40
+ assert_kind_of BentoSearch::Results, results[key]
41
+ end
42
+
43
+ # call results again, we get the exact same hash back.
44
+ new_results = searcher.results
45
+ assert_kind_of Hash, new_results
46
+ assert( results.equal? new_results )
47
+ end
48
+
49
+ def test_results_before_search
50
+ searcher = BentoSearch::ConcurrentSearcher.new(:one, :two, :three)
51
+
52
+ assert_raises(ArgumentError) do
53
+ results = searcher.results
54
+ end
55
+ end
56
+
57
+
58
+ def test_concurrent_search_uncaught_exception
59
+ searcher = BentoSearch::ConcurrentSearcher.new(:one, :raiser, :two)
60
+ results = searcher.search("cancer").results
61
+
62
+ [:one, :two].each do |success_engine_id|
63
+ assert( results[success_engine_id.to_s].kind_of?(BentoSearch::Results) )
64
+ assert( !results[success_engine_id.to_s].failed? )
65
+ end
66
+
67
+
68
+ error_results = results["raiser"]
69
+
70
+ assert( error_results.kind_of?(BentoSearch::Results) )
71
+ assert( error_results.failed? )
72
+ assert( error_results.error[:exception].present? )
73
+ assert( error_results.engine_id == "raiser" )
74
+ end
75
+ end
@@ -21,29 +21,26 @@ class MultiSearcherTest < ActiveSupport::TestCase
21
21
 
22
22
 
23
23
  def test_multisearch
24
- searcher = BentoSearch::MultiSearcher.new(:one, :two, :three)
25
- start_returnval = searcher.start("cancer")
24
+ ActiveSupport::Deprecation.silence do
25
+ searcher = BentoSearch::MultiSearcher.new(:one, :two, :three)
26
+ start_returnval = searcher.start("cancer")
26
27
 
27
- assert_same searcher, start_returnval
28
+ assert_same searcher, start_returnval
28
29
 
29
- results = searcher.results
30
+ results = searcher.results
30
31
 
31
- assert_kind_of Hash, results
32
- assert_equal ["one", "two", "three"].sort, results.keys.sort
32
+ assert_kind_of Hash, results
33
+ assert_equal ["one", "two", "three"].sort, results.keys.sort
33
34
 
34
- ["one", "two", "three"].each do |key|
35
- assert_kind_of BentoSearch::Results, results[key]
36
- end
37
-
38
- # call results again, we get an empty hash, can only call
39
- # results once per start.
40
- new_results = searcher.results
41
- assert_kind_of Hash, new_results
42
- assert_empty new_results
35
+ ["one", "two", "three"].each do |key|
36
+ assert_kind_of BentoSearch::Results, results[key]
37
+ end
43
38
 
39
+ # call results again, we get an empty hash, can only call
40
+ # results once per start.
41
+ new_results = searcher.results
42
+ assert_kind_of Hash, new_results
43
+ assert_empty new_results
44
+ end
44
45
  end
45
-
46
-
47
-
48
-
49
46
  end